﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Mesh
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.Bindings;
using UnityEngine.Internal;
using UnityEngine.Rendering;
using UnityEngine.Scripting;

#nullable disable
namespace UnityEngine
{
  /// <summary>
  ///   <para>A class that allows you to create or modify meshes.</para>
  /// </summary>
  [NativeHeader("Runtime/Graphics/Mesh/MeshScriptBindings.h")]
  [RequiredByNativeCode]
  public sealed class Mesh : Object
  {
    [Obsolete("Property Mesh.uv1 has been deprecated. Use Mesh.uv2 instead (UnityUpgradable) -> uv2", true)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public Vector2[] uv1
    {
      get => (Vector2[]) null;
      set
      {
      }
    }

    [FreeFunction("MeshScripting::CreateMesh")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void Internal_Create([Writable] Mesh mono);

    /// <summary>
    ///   <para>Creates an empty Mesh.</para>
    /// </summary>
    [RequiredByNativeCode]
    public Mesh() => Mesh.Internal_Create(this);

    [FreeFunction("MeshScripting::MeshFromInstanceId")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    internal static extern Mesh FromInstanceID(int id);

    /// <summary>
    ///   <para>Format of the mesh index buffer data.</para>
    /// </summary>
    public extern IndexFormat indexFormat { [MethodImpl(MethodImplOptions.InternalCall)] get; [MethodImpl(MethodImplOptions.InternalCall)] set; }

    [MethodImpl(MethodImplOptions.InternalCall)]
    internal extern uint GetTotalIndexCount();

    /// <summary>
    ///   <para>Sets the index buffer size and format.</para>
    /// </summary>
    /// <param name="indexCount">Size of index buffer.</param>
    /// <param name="format">Format of the indices.</param>
    [FreeFunction(Name = "MeshScripting::SetIndexBufferParams", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void SetIndexBufferParams(int indexCount, IndexFormat format);

    [FreeFunction(Name = "MeshScripting::InternalSetIndexBufferData", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void InternalSetIndexBufferData(
      IntPtr data,
      int dataStart,
      int meshBufferStart,
      int count,
      int elemSize,
      MeshUpdateFlags flags);

    [FreeFunction(Name = "MeshScripting::InternalSetIndexBufferDataFromArray", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void InternalSetIndexBufferDataFromArray(
      Array data,
      int dataStart,
      int meshBufferStart,
      int count,
      int elemSize,
      MeshUpdateFlags flags);

    [FreeFunction(Name = "MeshScripting::SetVertexBufferParamsFromPtr", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetVertexBufferParamsFromPtr(
      int vertexCount,
      IntPtr attributesPtr,
      int attributesCount);

    [FreeFunction(Name = "MeshScripting::SetVertexBufferParamsFromArray", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetVertexBufferParamsFromArray(
      int vertexCount,
      [Unmarshalled] params VertexAttributeDescriptor[] attributes);

    [FreeFunction(Name = "MeshScripting::InternalSetVertexBufferData", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void InternalSetVertexBufferData(
      int stream,
      IntPtr data,
      int dataStart,
      int meshBufferStart,
      int count,
      int elemSize,
      MeshUpdateFlags flags);

    [FreeFunction(Name = "MeshScripting::InternalSetVertexBufferDataFromArray", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void InternalSetVertexBufferDataFromArray(
      int stream,
      Array data,
      int dataStart,
      int meshBufferStart,
      int count,
      int elemSize,
      MeshUpdateFlags flags);

    [FreeFunction(Name = "MeshScripting::GetVertexAttributesAlloc", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern Array GetVertexAttributesAlloc();

    [FreeFunction(Name = "MeshScripting::GetVertexAttributesArray", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int GetVertexAttributesArray([NotNull("ArgumentNullException"), Unmarshalled] VertexAttributeDescriptor[] attributes);

    [FreeFunction(Name = "MeshScripting::GetVertexAttributesList", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int GetVertexAttributesList([NotNull("ArgumentNullException")] List<VertexAttributeDescriptor> attributes);

    [FreeFunction(Name = "MeshScripting::GetVertexAttributesCount", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int GetVertexAttributeCountImpl();

    /// <summary>
    ///   <para>Returns information about a vertex attribute based on its index.</para>
    /// </summary>
    /// <param name="index">The vertex attribute index (0 to vertexAttributeCount-1).</param>
    /// <returns>
    ///   <para>Information about the vertex attribute.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetVertexAttributeByIndex", HasExplicitThis = true, ThrowsException = true)]
    public VertexAttributeDescriptor GetVertexAttribute(int index)
    {
      VertexAttributeDescriptor ret;
      this.GetVertexAttribute_Injected(index, out ret);
      return ret;
    }

    [FreeFunction(Name = "MeshScripting::GetIndexStart", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern uint GetIndexStartImpl(int submesh);

    [FreeFunction(Name = "MeshScripting::GetIndexCount", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern uint GetIndexCountImpl(int submesh);

    [FreeFunction(Name = "MeshScripting::GetTrianglesCount", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern uint GetTrianglesCountImpl(int submesh);

    [FreeFunction(Name = "MeshScripting::GetBaseVertex", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern uint GetBaseVertexImpl(int submesh);

    [FreeFunction(Name = "MeshScripting::GetTriangles", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int[] GetTrianglesImpl(int submesh, bool applyBaseVertex);

    [FreeFunction(Name = "MeshScripting::GetIndices", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int[] GetIndicesImpl(int submesh, bool applyBaseVertex);

    [FreeFunction(Name = "SetMeshIndicesFromScript", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetIndicesImpl(
      int submesh,
      MeshTopology topology,
      IndexFormat indicesFormat,
      Array indices,
      int arrayStart,
      int arraySize,
      bool calculateBounds,
      int baseVertex);

    [FreeFunction(Name = "SetMeshIndicesFromNativeArray", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetIndicesNativeArrayImpl(
      int submesh,
      MeshTopology topology,
      IndexFormat indicesFormat,
      IntPtr indices,
      int arrayStart,
      int arraySize,
      bool calculateBounds,
      int baseVertex);

    [FreeFunction(Name = "MeshScripting::ExtractTrianglesToArray", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetTrianglesNonAllocImpl([Out] int[] values, int submesh, bool applyBaseVertex);

    [FreeFunction(Name = "MeshScripting::ExtractTrianglesToArray16", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetTrianglesNonAllocImpl16(
      [Out] ushort[] values,
      int submesh,
      bool applyBaseVertex);

    [FreeFunction(Name = "MeshScripting::ExtractIndicesToArray", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetIndicesNonAllocImpl([Out] int[] values, int submesh, bool applyBaseVertex);

    [FreeFunction(Name = "MeshScripting::ExtractIndicesToArray16", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetIndicesNonAllocImpl16(
      [Out] ushort[] values,
      int submesh,
      bool applyBaseVertex);

    [FreeFunction(Name = "MeshScripting::PrintErrorCantAccessChannel", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void PrintErrorCantAccessChannel(VertexAttribute ch);

    /// <summary>
    ///   <para>Checks if a specific vertex data attribute exists on this Mesh.</para>
    /// </summary>
    /// <param name="attr">Vertex data attribute to check for.</param>
    /// <returns>
    ///   <para>Returns true if the data attribute is present in the mesh.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::HasChannel", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern bool HasVertexAttribute(VertexAttribute attr);

    /// <summary>
    ///   <para>Get dimension of a specific vertex data attribute on this Mesh.</para>
    /// </summary>
    /// <param name="attr">Vertex data attribute to check for.</param>
    /// <returns>
    ///   <para>Dimensionality of the data attribute, or zero if it is not present.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetChannelDimension", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern int GetVertexAttributeDimension(VertexAttribute attr);

    /// <summary>
    ///   <para>Get format of a specific vertex data attribute on this Mesh.</para>
    /// </summary>
    /// <param name="attr">Vertex data attribute to check for.</param>
    /// <returns>
    ///   <para>Format of the data attribute.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetChannelFormat", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern VertexAttributeFormat GetVertexAttributeFormat(VertexAttribute attr);

    /// <summary>
    ///   <para>Gets the vertex buffer stream index of a specific vertex data attribute on this Mesh.</para>
    /// </summary>
    /// <param name="attr">The vertex data attribute to check for.</param>
    /// <returns>
    ///   <para>Stream index of the data attribute, or -1 if it is not present.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetChannelStream", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern int GetVertexAttributeStream(VertexAttribute attr);

    /// <summary>
    ///   <para>Get offset within a vertex buffer stream of a specific vertex data attribute on this Mesh.</para>
    /// </summary>
    /// <param name="attr">The vertex data attribute to check for.</param>
    /// <returns>
    ///   <para>The byte offset within a atream of the data attribute, or -1 if it is not present.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetChannelOffset", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern int GetVertexAttributeOffset(VertexAttribute attr);

    [FreeFunction(Name = "SetMeshComponentFromArrayFromScript", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetArrayForChannelImpl(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim,
      Array values,
      int arraySize,
      int valuesStart,
      int valuesCount,
      MeshUpdateFlags flags);

    [FreeFunction(Name = "SetMeshComponentFromNativeArrayFromScript", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetNativeArrayForChannelImpl(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim,
      IntPtr values,
      int arraySize,
      int valuesStart,
      int valuesCount,
      MeshUpdateFlags flags);

    [FreeFunction(Name = "AllocExtractMeshComponentFromScript", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern Array GetAllocArrayFromChannelImpl(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim);

    [FreeFunction(Name = "ExtractMeshComponentFromScript", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetArrayFromChannelImpl(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim,
      Array values);

    /// <summary>
    ///   <para>Gets the number of vertex buffers present in the Mesh. (Read Only)</para>
    /// </summary>
    public extern int vertexBufferCount { [FreeFunction(Name = "MeshScripting::GetVertexBufferCount", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Get vertex buffer stream stride in bytes.</para>
    /// </summary>
    /// <param name="stream">Vertex data stream index to check for.</param>
    /// <returns>
    ///   <para>Vertex data size in bytes in this stream, or zero if the stream is not present.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetVertexBufferStride", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern int GetVertexBufferStride(int stream);

    /// <summary>
    ///   <para>Retrieves a native (underlying graphics API) pointer to the vertex buffer.</para>
    /// </summary>
    /// <param name="index">Which vertex buffer to get (some Meshes might have more than one). See vertexBufferCount.</param>
    /// <returns>
    ///   <para>Pointer to the underlying graphics API vertex buffer.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetNativeVertexBufferPtr", HasExplicitThis = true)]
    [NativeThrows]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern IntPtr GetNativeVertexBufferPtr(int index);

    /// <summary>
    ///   <para>Retrieves a native (underlying graphics API) pointer to the index buffer.</para>
    /// </summary>
    /// <returns>
    ///   <para>Pointer to the underlying graphics API index buffer.</para>
    /// </returns>
    [FreeFunction(Name = "MeshScripting::GetNativeIndexBufferPtr", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern IntPtr GetNativeIndexBufferPtr();

    [FreeFunction(Name = "MeshScripting::GetVertexBufferPtr", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern GraphicsBuffer GetVertexBufferImpl(int index);

    [FreeFunction(Name = "MeshScripting::GetIndexBufferPtr", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern GraphicsBuffer GetIndexBufferImpl();

    /// <summary>
    ///   <para>The intended target usage of the Mesh GPU vertex buffer.</para>
    /// </summary>
    public extern GraphicsBuffer.Target vertexBufferTarget { [MethodImpl(MethodImplOptions.InternalCall)] get; [MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>The intended target usage of the Mesh GPU index buffer.</para>
    /// </summary>
    public extern GraphicsBuffer.Target indexBufferTarget { [MethodImpl(MethodImplOptions.InternalCall)] get; [MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>Returns BlendShape count on this mesh.</para>
    /// </summary>
    public extern int blendShapeCount { [NativeMethod(Name = "GetBlendShapeChannelCount"), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Clears all blend shapes from Mesh.</para>
    /// </summary>
    [FreeFunction(Name = "MeshScripting::ClearBlendShapes", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void ClearBlendShapes();

    /// <summary>
    ///   <para>Returns name of BlendShape by given index.</para>
    /// </summary>
    /// <param name="shapeIndex"></param>
    [FreeFunction(Name = "MeshScripting::GetBlendShapeName", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern string GetBlendShapeName(int shapeIndex);

    /// <summary>
    ///   <para>Returns index of BlendShape by given name.</para>
    /// </summary>
    /// <param name="blendShapeName"></param>
    [FreeFunction(Name = "MeshScripting::GetBlendShapeIndex", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern int GetBlendShapeIndex(string blendShapeName);

    /// <summary>
    ///   <para>Returns the frame count for a blend shape.</para>
    /// </summary>
    /// <param name="shapeIndex">The shape index to get frame count from.</param>
    [FreeFunction(Name = "MeshScripting::GetBlendShapeFrameCount", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern int GetBlendShapeFrameCount(int shapeIndex);

    /// <summary>
    ///   <para>Returns the weight of a blend shape frame.</para>
    /// </summary>
    /// <param name="shapeIndex">The shape index of the frame.</param>
    /// <param name="frameIndex">The frame index to get the weight from.</param>
    [FreeFunction(Name = "MeshScripting::GetBlendShapeFrameWeight", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern float GetBlendShapeFrameWeight(int shapeIndex, int frameIndex);

    /// <summary>
    ///   <para>Retreives deltaVertices, deltaNormals and deltaTangents of a blend shape frame.</para>
    /// </summary>
    /// <param name="shapeIndex">The shape index of the frame.</param>
    /// <param name="frameIndex">The frame index to get the weight from.</param>
    /// <param name="deltaVertices">Delta vertices output array for the frame being retreived.</param>
    /// <param name="deltaNormals">Delta normals output array for the frame being retreived.</param>
    /// <param name="deltaTangents">Delta tangents output array for the frame being retreived.</param>
    [FreeFunction(Name = "GetBlendShapeFrameVerticesFromScript", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void GetBlendShapeFrameVertices(
      int shapeIndex,
      int frameIndex,
      [Unmarshalled] Vector3[] deltaVertices,
      [Unmarshalled] Vector3[] deltaNormals,
      [Unmarshalled] Vector3[] deltaTangents);

    /// <summary>
    ///   <para>Adds a new blend shape frame.</para>
    /// </summary>
    /// <param name="shapeName">Name of the blend shape to add a frame to.</param>
    /// <param name="frameWeight">Weight for the frame being added.</param>
    /// <param name="deltaVertices">Delta vertices for the frame being added.</param>
    /// <param name="deltaNormals">Delta normals for the frame being added.</param>
    /// <param name="deltaTangents">Delta tangents for the frame being added.</param>
    [FreeFunction(Name = "AddBlendShapeFrameFromScript", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void AddBlendShapeFrame(
      string shapeName,
      float frameWeight,
      [Unmarshalled] Vector3[] deltaVertices,
      [Unmarshalled] Vector3[] deltaNormals,
      [Unmarshalled] Vector3[] deltaTangents);

    [NativeMethod("HasBoneWeights")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern bool HasBoneWeights();

    [FreeFunction(Name = "MeshScripting::GetBoneWeights", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern BoneWeight[] GetBoneWeightsImpl();

    [FreeFunction(Name = "MeshScripting::SetBoneWeights", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetBoneWeightsImpl(BoneWeight[] weights);

    public unsafe void SetBoneWeights(
      NativeArray<byte> bonesPerVertex,
      NativeArray<BoneWeight1> weights)
    {
      this.InternalSetBoneWeights((IntPtr) bonesPerVertex.GetUnsafeReadOnlyPtr<byte>(), bonesPerVertex.Length, (IntPtr) weights.GetUnsafeReadOnlyPtr<BoneWeight1>(), weights.Length);
    }

    [FreeFunction(Name = "MeshScripting::SetBoneWeights", HasExplicitThis = true)]
    [SecurityCritical]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void InternalSetBoneWeights(
      IntPtr bonesPerVertex,
      int bonesPerVertexSize,
      IntPtr weights,
      int weightsSize);

    /// <summary>
    ///   <para>Gets the bone weights for the Mesh.</para>
    /// </summary>
    /// <returns>
    ///   <para>Returns all non-zero bone weights for the Mesh, in vertex index order.</para>
    /// </returns>
    public unsafe NativeArray<BoneWeight1> GetAllBoneWeights()
    {
      NativeArray<BoneWeight1> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<BoneWeight1>((void*) this.GetAllBoneWeightsArray(), this.GetAllBoneWeightsArraySize(), Allocator.None);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<BoneWeight1>(ref nativeArray, this.GetReadOnlySafetyHandle(Mesh.SafetyHandleIndex.BonesWeightsArray));
      return nativeArray;
    }

    /// <summary>
    ///   <para>The number of non-zero bone weights for each vertex.</para>
    /// </summary>
    /// <returns>
    ///   <para>Returns the number of non-zero bone weights for each vertex.</para>
    /// </returns>
    public unsafe NativeArray<byte> GetBonesPerVertex()
    {
      int vertexCount = this.HasBoneWeights() ? this.vertexCount : 0;
      NativeArray<byte> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>((void*) this.GetBonesPerVertexArray(), vertexCount, Allocator.None);
      NativeArrayUnsafeUtility.SetAtomicSafetyHandle<byte>(ref nativeArray, this.GetReadOnlySafetyHandle(Mesh.SafetyHandleIndex.BonesPerVertexArray));
      return nativeArray;
    }

    [FreeFunction(Name = "MeshScripting::GetAllBoneWeightsArraySize", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int GetAllBoneWeightsArraySize();

    [SecurityCritical]
    [FreeFunction(Name = "MeshScripting::GetAllBoneWeightsArray", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern IntPtr GetAllBoneWeightsArray();

    [FreeFunction(Name = "MeshScripting::GetBonesPerVertexArray", HasExplicitThis = true)]
    [SecurityCritical]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern IntPtr GetBonesPerVertexArray();

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern int GetBindposeCount();

    /// <summary>
    ///   <para>The bind poses. The bind pose at each index refers to the bone with the same index.</para>
    /// </summary>
    [NativeName("BindPosesFromScript")]
    public extern Matrix4x4[] bindposes { [MethodImpl(MethodImplOptions.InternalCall)] get; [MethodImpl(MethodImplOptions.InternalCall)] set; }

    [FreeFunction(Name = "MeshScripting::ExtractBoneWeightsIntoArray", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetBoneWeightsNonAllocImpl([Out] BoneWeight[] values);

    [FreeFunction(Name = "MeshScripting::ExtractBindPosesIntoArray", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetBindposesNonAllocImpl([Out] Matrix4x4[] values);

    [FreeFunction(Name = "MeshScripting::GetReadOnlySafetyHandle", HasExplicitThis = true)]
    private AtomicSafetyHandle GetReadOnlySafetyHandle(Mesh.SafetyHandleIndex index)
    {
      AtomicSafetyHandle ret;
      this.GetReadOnlySafetyHandle_Injected(index, out ret);
      return ret;
    }

    [FreeFunction(Name = "MeshScripting::IsCloudResource", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    internal extern bool IsCloudResource();

    /// <summary>
    ///   <para>Returns true if the Mesh is read/write enabled, or false if it is not.</para>
    /// </summary>
    public extern bool isReadable { [NativeMethod("GetIsReadable"), MethodImpl(MethodImplOptions.InternalCall)] get; }

    internal extern bool canAccess { [NativeMethod("CanAccessFromScript"), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>Returns the number of vertices in the Mesh (Read Only).</para>
    /// </summary>
    public extern int vertexCount { [NativeMethod("GetVertexCount"), MethodImpl(MethodImplOptions.InternalCall)] get; }

    /// <summary>
    ///   <para>The number of sub-meshes inside the Mesh object.</para>
    /// </summary>
    public extern int subMeshCount { [NativeMethod(Name = "GetSubMeshCount"), MethodImpl(MethodImplOptions.InternalCall)] get; [FreeFunction(Name = "MeshScripting::SetSubMeshCount", HasExplicitThis = true), MethodImpl(MethodImplOptions.InternalCall)] set; }

    /// <summary>
    ///   <para>Sets the information about a sub-mesh of the Mesh.</para>
    /// </summary>
    /// <param name="index">Sub-mesh index. See subMeshCount. Out of range indices throw an exception.</param>
    /// <param name="desc">Sub-mesh data.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [FreeFunction("MeshScripting::SetSubMesh", HasExplicitThis = true, ThrowsException = true)]
    public void SetSubMesh(int index, SubMeshDescriptor desc, MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      this.SetSubMesh_Injected(index, ref desc, flags);
    }

    /// <summary>
    ///   <para>Get information about a sub-mesh of the Mesh.</para>
    /// </summary>
    /// <param name="index">Sub-mesh index. See subMeshCount. Out of range indices throw an exception.</param>
    /// <returns>
    ///   <para>Sub-mesh data.</para>
    /// </returns>
    [FreeFunction("MeshScripting::GetSubMesh", HasExplicitThis = true, ThrowsException = true)]
    public SubMeshDescriptor GetSubMesh(int index)
    {
      SubMeshDescriptor ret;
      this.GetSubMesh_Injected(index, out ret);
      return ret;
    }

    [FreeFunction("MeshScripting::SetAllSubMeshesAtOnceFromArray", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetAllSubMeshesAtOnceFromArray(
      SubMeshDescriptor[] desc,
      int start,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default);

    [FreeFunction("MeshScripting::SetAllSubMeshesAtOnceFromNativeArray", HasExplicitThis = true, ThrowsException = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetAllSubMeshesAtOnceFromNativeArray(
      IntPtr desc,
      int start,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default);

    /// <summary>
    ///   <para>The bounding volume of the Mesh.</para>
    /// </summary>
    public Bounds bounds
    {
      get
      {
        Bounds ret;
        this.get_bounds_Injected(out ret);
        return ret;
      }
      set => this.set_bounds_Injected(ref value);
    }

    [NativeMethod("Clear")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void ClearImpl(bool keepVertexLayout);

    [NativeMethod("RecalculateBounds")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void RecalculateBoundsImpl(MeshUpdateFlags flags);

    [NativeMethod("RecalculateNormals")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void RecalculateNormalsImpl(MeshUpdateFlags flags);

    [NativeMethod("RecalculateTangents")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void RecalculateTangentsImpl(MeshUpdateFlags flags);

    [NativeMethod("MarkDynamic")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void MarkDynamicImpl();

    /// <summary>
    ///   <para>Notify Renderer components of mesh geometry change.</para>
    /// </summary>
    [NativeMethod("MarkModified")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void MarkModified();

    [NativeMethod("UploadMeshData")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void UploadMeshDataImpl(bool markNoLongerReadable);

    [FreeFunction(Name = "MeshScripting::GetPrimitiveType", HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern MeshTopology GetTopologyImpl(int submesh);

    [NativeMethod("RecalculateMeshMetric")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void RecalculateUVDistributionMetricImpl(int uvSetIndex, float uvAreaThreshold);

    [NativeMethod("RecalculateMeshMetrics")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void RecalculateUVDistributionMetricsImpl(float uvAreaThreshold);

    /// <summary>
    ///   <para>The UV distribution metric can be used to calculate the desired mipmap level based on the position of the camera.</para>
    /// </summary>
    /// <param name="uvSetIndex">UV set index to return the UV distibution metric for. 0 for first.</param>
    /// <returns>
    ///   <para>Average of triangle area / uv area.</para>
    /// </returns>
    [NativeMethod("GetMeshMetric")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern float GetUVDistributionMetric(int uvSetIndex);

    [NativeMethod(Name = "MeshScripting::CombineMeshes", IsFreeFunction = true, ThrowsException = true, HasExplicitThis = true)]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void CombineMeshesImpl(
      CombineInstance[] combine,
      bool mergeSubMeshes,
      bool useMatrices,
      bool hasLightmapData);

    [NativeMethod("Optimize")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void OptimizeImpl();

    [NativeMethod("OptimizeIndexBuffers")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void OptimizeIndexBuffersImpl();

    [NativeMethod("OptimizeReorderVertexBuffer")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void OptimizeReorderVertexBufferImpl();

    internal static VertexAttribute GetUVChannel(int uvIndex)
    {
      if (uvIndex < 0 || uvIndex > 7)
        throw new ArgumentException("GetUVChannel called for bad uvIndex", nameof (uvIndex));
      return (VertexAttribute) (4 + uvIndex);
    }

    internal static int DefaultDimensionForChannel(VertexAttribute channel)
    {
      if (channel == VertexAttribute.Position || channel == VertexAttribute.Normal)
        return 3;
      if (channel >= VertexAttribute.TexCoord0 && channel <= VertexAttribute.TexCoord7)
        return 2;
      if (channel == VertexAttribute.Tangent || channel == VertexAttribute.Color)
        return 4;
      throw new ArgumentException("DefaultDimensionForChannel called for bad channel", nameof (channel));
    }

    private T[] GetAllocArrayFromChannel<T>(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim)
    {
      if (this.canAccess)
      {
        if (this.HasVertexAttribute(channel))
          return (T[]) this.GetAllocArrayFromChannelImpl(channel, format, dim);
      }
      else
        this.PrintErrorCantAccessChannel(channel);
      return new T[0];
    }

    private T[] GetAllocArrayFromChannel<T>(VertexAttribute channel)
    {
      return this.GetAllocArrayFromChannel<T>(channel, VertexAttributeFormat.Float32, Mesh.DefaultDimensionForChannel(channel));
    }

    private void SetSizedArrayForChannel(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim,
      Array values,
      int valuesArrayLength,
      int valuesStart,
      int valuesCount,
      MeshUpdateFlags flags)
    {
      if (this.canAccess)
      {
        if (valuesStart < 0)
          throw new ArgumentOutOfRangeException(nameof (valuesStart), (object) valuesStart, "Mesh data array start index can't be negative.");
        if (valuesCount < 0)
          throw new ArgumentOutOfRangeException(nameof (valuesCount), (object) valuesCount, "Mesh data array length can't be negative.");
        if (valuesStart >= valuesArrayLength && valuesCount != 0)
          throw new ArgumentOutOfRangeException(nameof (valuesStart), (object) valuesStart, "Mesh data array start is outside of array size.");
        if (valuesStart + valuesCount > valuesArrayLength)
          throw new ArgumentOutOfRangeException(nameof (valuesCount), (object) (valuesStart + valuesCount), "Mesh data array start+count is outside of array size.");
        if (values == null)
          valuesStart = 0;
        this.SetArrayForChannelImpl(channel, format, dim, values, valuesArrayLength, valuesStart, valuesCount, flags);
      }
      else
        this.PrintErrorCantAccessChannel(channel);
    }

    private void SetSizedNativeArrayForChannel(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim,
      IntPtr values,
      int valuesArrayLength,
      int valuesStart,
      int valuesCount,
      MeshUpdateFlags flags)
    {
      if (this.canAccess)
      {
        if (valuesStart < 0)
          throw new ArgumentOutOfRangeException(nameof (valuesStart), (object) valuesStart, "Mesh data array start index can't be negative.");
        if (valuesCount < 0)
          throw new ArgumentOutOfRangeException(nameof (valuesCount), (object) valuesCount, "Mesh data array length can't be negative.");
        if (valuesStart >= valuesArrayLength && valuesCount != 0)
          throw new ArgumentOutOfRangeException(nameof (valuesStart), (object) valuesStart, "Mesh data array start is outside of array size.");
        if (valuesStart + valuesCount > valuesArrayLength)
          throw new ArgumentOutOfRangeException(nameof (valuesCount), (object) (valuesStart + valuesCount), "Mesh data array start+count is outside of array size.");
        this.SetNativeArrayForChannelImpl(channel, format, dim, values, valuesArrayLength, valuesStart, valuesCount, flags);
      }
      else
        this.PrintErrorCantAccessChannel(channel);
    }

    private void SetArrayForChannel<T>(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim,
      T[] values,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      int num = NoAllocHelpers.SafeLength((Array) values);
      this.SetSizedArrayForChannel(channel, format, dim, (Array) values, num, 0, num, flags);
    }

    private void SetArrayForChannel<T>(VertexAttribute channel, T[] values, MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      int num = NoAllocHelpers.SafeLength((Array) values);
      this.SetSizedArrayForChannel(channel, VertexAttributeFormat.Float32, Mesh.DefaultDimensionForChannel(channel), (Array) values, num, 0, num, flags);
    }

    private void SetListForChannel<T>(
      VertexAttribute channel,
      VertexAttributeFormat format,
      int dim,
      List<T> values,
      int start,
      int length,
      MeshUpdateFlags flags)
    {
      this.SetSizedArrayForChannel(channel, format, dim, NoAllocHelpers.ExtractArrayFromList((object) values), NoAllocHelpers.SafeLength<T>(values), start, length, flags);
    }

    private void SetListForChannel<T>(
      VertexAttribute channel,
      List<T> values,
      int start,
      int length,
      MeshUpdateFlags flags)
    {
      this.SetSizedArrayForChannel(channel, VertexAttributeFormat.Float32, Mesh.DefaultDimensionForChannel(channel), NoAllocHelpers.ExtractArrayFromList((object) values), NoAllocHelpers.SafeLength<T>(values), start, length, flags);
    }

    private void GetListForChannel<T>(
      List<T> buffer,
      int capacity,
      VertexAttribute channel,
      int dim)
    {
      this.GetListForChannel<T>(buffer, capacity, channel, dim, VertexAttributeFormat.Float32);
    }

    private void GetListForChannel<T>(
      List<T> buffer,
      int capacity,
      VertexAttribute channel,
      int dim,
      VertexAttributeFormat channelType)
    {
      buffer.Clear();
      if (!this.canAccess)
      {
        this.PrintErrorCantAccessChannel(channel);
      }
      else
      {
        if (!this.HasVertexAttribute(channel))
          return;
        NoAllocHelpers.EnsureListElemCount<T>(buffer, capacity);
        this.GetArrayFromChannelImpl(channel, channelType, dim, NoAllocHelpers.ExtractArrayFromList((object) buffer));
      }
    }

    /// <summary>
    ///   <para>Returns a copy of the vertex positions or assigns a new vertex positions array.</para>
    /// </summary>
    public Vector3[] vertices
    {
      get => this.GetAllocArrayFromChannel<Vector3>(VertexAttribute.Position);
      set => this.SetArrayForChannel<Vector3>(VertexAttribute.Position, value);
    }

    /// <summary>
    ///   <para>The normals of the Mesh.</para>
    /// </summary>
    public Vector3[] normals
    {
      get => this.GetAllocArrayFromChannel<Vector3>(VertexAttribute.Normal);
      set => this.SetArrayForChannel<Vector3>(VertexAttribute.Normal, value);
    }

    /// <summary>
    ///   <para>The tangents of the Mesh.</para>
    /// </summary>
    public Vector4[] tangents
    {
      get => this.GetAllocArrayFromChannel<Vector4>(VertexAttribute.Tangent);
      set => this.SetArrayForChannel<Vector4>(VertexAttribute.Tangent, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the first channel.</para>
    /// </summary>
    public Vector2[] uv
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord0);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord0, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the second channel.</para>
    /// </summary>
    public Vector2[] uv2
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord1);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord1, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the third channel.</para>
    /// </summary>
    public Vector2[] uv3
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord2);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord2, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the fourth channel.</para>
    /// </summary>
    public Vector2[] uv4
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord3);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord3, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the fifth channel.</para>
    /// </summary>
    public Vector2[] uv5
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord4);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord4, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the sixth channel.</para>
    /// </summary>
    public Vector2[] uv6
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord5);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord5, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the seventh channel.</para>
    /// </summary>
    public Vector2[] uv7
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord6);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord6, value);
    }

    /// <summary>
    ///   <para>The texture coordinates (UVs) in the eighth channel.</para>
    /// </summary>
    public Vector2[] uv8
    {
      get => this.GetAllocArrayFromChannel<Vector2>(VertexAttribute.TexCoord7);
      set => this.SetArrayForChannel<Vector2>(VertexAttribute.TexCoord7, value);
    }

    /// <summary>
    ///   <para>Vertex colors of the Mesh.</para>
    /// </summary>
    public Color[] colors
    {
      get => this.GetAllocArrayFromChannel<Color>(VertexAttribute.Color);
      set => this.SetArrayForChannel<Color>(VertexAttribute.Color, value);
    }

    /// <summary>
    ///   <para>Vertex colors of the Mesh.</para>
    /// </summary>
    public Color32[] colors32
    {
      get
      {
        return this.GetAllocArrayFromChannel<Color32>(VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4);
      }
      set
      {
        this.SetArrayForChannel<Color32>(VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4, value);
      }
    }

    public void GetVertices(List<Vector3> vertices)
    {
      if (vertices == null)
        throw new ArgumentNullException(nameof (vertices), "The result vertices list cannot be null.");
      this.GetListForChannel<Vector3>(vertices, this.vertexCount, VertexAttribute.Position, Mesh.DefaultDimensionForChannel(VertexAttribute.Position));
    }

    public void SetVertices(List<Vector3> inVertices)
    {
      this.SetVertices(inVertices, 0, NoAllocHelpers.SafeLength<Vector3>(inVertices));
    }

    [ExcludeFromDocs]
    public void SetVertices(List<Vector3> inVertices, int start, int length)
    {
      this.SetVertices(inVertices, start, length, MeshUpdateFlags.Default);
    }

    public void SetVertices(
      List<Vector3> inVertices,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetListForChannel<Vector3>(VertexAttribute.Position, inVertices, start, length, flags);
    }

    /// <summary>
    ///   <para>Assigns a new vertex positions array.</para>
    /// </summary>
    /// <param name="inVertices">Per-vertex positions.</param>
    public void SetVertices(Vector3[] inVertices)
    {
      this.SetVertices(inVertices, 0, NoAllocHelpers.SafeLength((Array) inVertices));
    }

    /// <summary>
    ///   <para>Sets the vertex positions of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inVertices">Per-vertex positions.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetVertices(Vector3[] inVertices, int start, int length)
    {
      this.SetVertices(inVertices, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the vertex positions of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inVertices">Per-vertex positions.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetVertices(Vector3[] inVertices, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetSizedArrayForChannel(VertexAttribute.Position, VertexAttributeFormat.Float32, Mesh.DefaultDimensionForChannel(VertexAttribute.Position), (Array) inVertices, NoAllocHelpers.SafeLength((Array) inVertices), start, length, flags);
    }

    public void SetVertices<T>(NativeArray<T> inVertices) where T : struct
    {
      this.SetVertices<T>(inVertices, 0, inVertices.Length);
    }

    [ExcludeFromDocs]
    public void SetVertices<T>(NativeArray<T> inVertices, int start, int length) where T : struct
    {
      this.SetVertices<T>(inVertices, start, length, MeshUpdateFlags.Default);
    }

    public unsafe void SetVertices<T>(
      NativeArray<T> inVertices,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
      where T : struct
    {
      if (UnsafeUtility.SizeOf<T>() != 12)
        throw new ArgumentException("SetVertices with NativeArray should use struct type that is 12 bytes (3x float) in size");
      this.SetSizedNativeArrayForChannel(VertexAttribute.Position, VertexAttributeFormat.Float32, 3, (IntPtr) inVertices.GetUnsafeReadOnlyPtr<T>(), inVertices.Length, start, length, flags);
    }

    public void GetNormals(List<Vector3> normals)
    {
      if (normals == null)
        throw new ArgumentNullException(nameof (normals), "The result normals list cannot be null.");
      this.GetListForChannel<Vector3>(normals, this.vertexCount, VertexAttribute.Normal, Mesh.DefaultDimensionForChannel(VertexAttribute.Normal));
    }

    public void SetNormals(List<Vector3> inNormals)
    {
      this.SetNormals(inNormals, 0, NoAllocHelpers.SafeLength<Vector3>(inNormals));
    }

    [ExcludeFromDocs]
    public void SetNormals(List<Vector3> inNormals, int start, int length)
    {
      this.SetNormals(inNormals, start, length, MeshUpdateFlags.Default);
    }

    public void SetNormals(List<Vector3> inNormals, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetListForChannel<Vector3>(VertexAttribute.Normal, inNormals, start, length, flags);
    }

    /// <summary>
    ///   <para>Set the normals of the Mesh.</para>
    /// </summary>
    /// <param name="inNormals">Per-vertex normals.</param>
    public void SetNormals(Vector3[] inNormals)
    {
      this.SetNormals(inNormals, 0, NoAllocHelpers.SafeLength((Array) inNormals));
    }

    /// <summary>
    ///   <para>Sets the vertex normals of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inNormals">Per-vertex normals.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetNormals(Vector3[] inNormals, int start, int length)
    {
      this.SetNormals(inNormals, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the vertex normals of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inNormals">Per-vertex normals.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetNormals(Vector3[] inNormals, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetSizedArrayForChannel(VertexAttribute.Normal, VertexAttributeFormat.Float32, Mesh.DefaultDimensionForChannel(VertexAttribute.Normal), (Array) inNormals, NoAllocHelpers.SafeLength((Array) inNormals), start, length, flags);
    }

    public void SetNormals<T>(NativeArray<T> inNormals) where T : struct
    {
      this.SetNormals<T>(inNormals, 0, inNormals.Length);
    }

    [ExcludeFromDocs]
    public void SetNormals<T>(NativeArray<T> inNormals, int start, int length) where T : struct
    {
      this.SetNormals<T>(inNormals, start, length, MeshUpdateFlags.Default);
    }

    public unsafe void SetNormals<T>(
      NativeArray<T> inNormals,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
      where T : struct
    {
      if (UnsafeUtility.SizeOf<T>() != 12)
        throw new ArgumentException("SetNormals with NativeArray should use struct type that is 12 bytes (3x float) in size");
      this.SetSizedNativeArrayForChannel(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3, (IntPtr) inNormals.GetUnsafeReadOnlyPtr<T>(), inNormals.Length, start, length, flags);
    }

    public void GetTangents(List<Vector4> tangents)
    {
      if (tangents == null)
        throw new ArgumentNullException(nameof (tangents), "The result tangents list cannot be null.");
      this.GetListForChannel<Vector4>(tangents, this.vertexCount, VertexAttribute.Tangent, Mesh.DefaultDimensionForChannel(VertexAttribute.Tangent));
    }

    public void SetTangents(List<Vector4> inTangents)
    {
      this.SetTangents(inTangents, 0, NoAllocHelpers.SafeLength<Vector4>(inTangents));
    }

    [ExcludeFromDocs]
    public void SetTangents(List<Vector4> inTangents, int start, int length)
    {
      this.SetTangents(inTangents, start, length, MeshUpdateFlags.Default);
    }

    public void SetTangents(
      List<Vector4> inTangents,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetListForChannel<Vector4>(VertexAttribute.Tangent, inTangents, start, length, flags);
    }

    /// <summary>
    ///   <para>Set the tangents of the Mesh.</para>
    /// </summary>
    /// <param name="inTangents">Per-vertex tangents.</param>
    public void SetTangents(Vector4[] inTangents)
    {
      this.SetTangents(inTangents, 0, NoAllocHelpers.SafeLength((Array) inTangents));
    }

    /// <summary>
    ///   <para>Sets the tangents of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inTangents">Per-vertex tangents.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetTangents(Vector4[] inTangents, int start, int length)
    {
      this.SetTangents(inTangents, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the tangents of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inTangents">Per-vertex tangents.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetTangents(Vector4[] inTangents, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetSizedArrayForChannel(VertexAttribute.Tangent, VertexAttributeFormat.Float32, Mesh.DefaultDimensionForChannel(VertexAttribute.Tangent), (Array) inTangents, NoAllocHelpers.SafeLength((Array) inTangents), start, length, flags);
    }

    public void SetTangents<T>(NativeArray<T> inTangents) where T : struct
    {
      this.SetTangents<T>(inTangents, 0, inTangents.Length);
    }

    [ExcludeFromDocs]
    public void SetTangents<T>(NativeArray<T> inTangents, int start, int length) where T : struct
    {
      this.SetTangents<T>(inTangents, start, length, MeshUpdateFlags.Default);
    }

    public unsafe void SetTangents<T>(
      NativeArray<T> inTangents,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
      where T : struct
    {
      if (UnsafeUtility.SizeOf<T>() != 16)
        throw new ArgumentException("SetTangents with NativeArray should use struct type that is 16 bytes (4x float) in size");
      this.SetSizedNativeArrayForChannel(VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4, (IntPtr) inTangents.GetUnsafeReadOnlyPtr<T>(), inTangents.Length, start, length, flags);
    }

    public void GetColors(List<Color> colors)
    {
      if (colors == null)
        throw new ArgumentNullException(nameof (colors), "The result colors list cannot be null.");
      this.GetListForChannel<Color>(colors, this.vertexCount, VertexAttribute.Color, Mesh.DefaultDimensionForChannel(VertexAttribute.Color));
    }

    public void SetColors(List<Color> inColors)
    {
      this.SetColors(inColors, 0, NoAllocHelpers.SafeLength<Color>(inColors));
    }

    [ExcludeFromDocs]
    public void SetColors(List<Color> inColors, int start, int length)
    {
      this.SetColors(inColors, start, length, MeshUpdateFlags.Default);
    }

    public void SetColors(List<Color> inColors, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetListForChannel<Color>(VertexAttribute.Color, inColors, start, length, flags);
    }

    /// <summary>
    ///   <para>Set the per-vertex colors of the Mesh.</para>
    /// </summary>
    /// <param name="inColors">Per-vertex colors.</param>
    public void SetColors(Color[] inColors)
    {
      this.SetColors(inColors, 0, NoAllocHelpers.SafeLength((Array) inColors));
    }

    /// <summary>
    ///   <para>Sets the per-vertex colors of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inColors">Per-vertex colors.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetColors(Color[] inColors, int start, int length)
    {
      this.SetColors(inColors, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the per-vertex colors of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inColors">Per-vertex colors.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetColors(Color[] inColors, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetSizedArrayForChannel(VertexAttribute.Color, VertexAttributeFormat.Float32, Mesh.DefaultDimensionForChannel(VertexAttribute.Color), (Array) inColors, NoAllocHelpers.SafeLength((Array) inColors), start, length, flags);
    }

    public void GetColors(List<Color32> colors)
    {
      if (colors == null)
        throw new ArgumentNullException(nameof (colors), "The result colors list cannot be null.");
      this.GetListForChannel<Color32>(colors, this.vertexCount, VertexAttribute.Color, 4, VertexAttributeFormat.UNorm8);
    }

    public void SetColors(List<Color32> inColors)
    {
      this.SetColors(inColors, 0, NoAllocHelpers.SafeLength<Color32>(inColors));
    }

    [ExcludeFromDocs]
    public void SetColors(List<Color32> inColors, int start, int length)
    {
      this.SetColors(inColors, start, length, MeshUpdateFlags.Default);
    }

    public void SetColors(List<Color32> inColors, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetListForChannel<Color32>(VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4, inColors, start, length, flags);
    }

    /// <summary>
    ///   <para>Set the per-vertex colors of the Mesh.</para>
    /// </summary>
    /// <param name="inColors">Per-vertex colors.</param>
    public void SetColors(Color32[] inColors)
    {
      this.SetColors(inColors, 0, NoAllocHelpers.SafeLength((Array) inColors));
    }

    /// <summary>
    ///   <para>Sets the per-vertex colors of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inColors">Per-vertex colors.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetColors(Color32[] inColors, int start, int length)
    {
      this.SetColors(inColors, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the per-vertex colors of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="inColors">Per-vertex colors.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetColors(Color32[] inColors, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetSizedArrayForChannel(VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4, (Array) inColors, NoAllocHelpers.SafeLength((Array) inColors), start, length, flags);
    }

    public void SetColors<T>(NativeArray<T> inColors) where T : struct
    {
      this.SetColors<T>(inColors, 0, inColors.Length);
    }

    [ExcludeFromDocs]
    public void SetColors<T>(NativeArray<T> inColors, int start, int length) where T : struct
    {
      this.SetColors<T>(inColors, start, length, MeshUpdateFlags.Default);
    }

    public unsafe void SetColors<T>(
      NativeArray<T> inColors,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
      where T : struct
    {
      int num = UnsafeUtility.SizeOf<T>();
      if (num != 16 && num != 4)
        throw new ArgumentException("SetColors with NativeArray should use struct type that is 16 bytes (4x float) or 4 bytes (4x unorm) in size");
      this.SetSizedNativeArrayForChannel(VertexAttribute.Color, num == 4 ? VertexAttributeFormat.UNorm8 : VertexAttributeFormat.Float32, 4, (IntPtr) inColors.GetUnsafeReadOnlyPtr<T>(), inColors.Length, start, length, flags);
    }

    private void SetUvsImpl<T>(
      int uvIndex,
      int dim,
      List<T> uvs,
      int start,
      int length,
      MeshUpdateFlags flags)
    {
      if (uvIndex < 0 || uvIndex > 7)
        Debug.LogError((object) "The uv index is invalid. Must be in the range 0 to 7.");
      else
        this.SetListForChannel<T>(Mesh.GetUVChannel(uvIndex), VertexAttributeFormat.Float32, dim, uvs, start, length, flags);
    }

    public void SetUVs(int channel, List<Vector2> uvs)
    {
      this.SetUVs(channel, uvs, 0, NoAllocHelpers.SafeLength<Vector2>(uvs));
    }

    public void SetUVs(int channel, List<Vector3> uvs)
    {
      this.SetUVs(channel, uvs, 0, NoAllocHelpers.SafeLength<Vector3>(uvs));
    }

    public void SetUVs(int channel, List<Vector4> uvs)
    {
      this.SetUVs(channel, uvs, 0, NoAllocHelpers.SafeLength<Vector4>(uvs));
    }

    [ExcludeFromDocs]
    public void SetUVs(int channel, List<Vector2> uvs, int start, int length)
    {
      this.SetUVs(channel, uvs, start, length, MeshUpdateFlags.Default);
    }

    public void SetUVs(
      int channel,
      List<Vector2> uvs,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetUvsImpl<Vector2>(channel, 2, uvs, start, length, flags);
    }

    [ExcludeFromDocs]
    public void SetUVs(int channel, List<Vector3> uvs, int start, int length)
    {
      this.SetUVs(channel, uvs, start, length, MeshUpdateFlags.Default);
    }

    public void SetUVs(
      int channel,
      List<Vector3> uvs,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetUvsImpl<Vector3>(channel, 3, uvs, start, length, flags);
    }

    [ExcludeFromDocs]
    public void SetUVs(int channel, List<Vector4> uvs, int start, int length)
    {
      this.SetUVs(channel, uvs, start, length, MeshUpdateFlags.Default);
    }

    public void SetUVs(
      int channel,
      List<Vector4> uvs,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetUvsImpl<Vector4>(channel, 4, uvs, start, length, flags);
    }

    private void SetUvsImpl(
      int uvIndex,
      int dim,
      Array uvs,
      int arrayStart,
      int arraySize,
      MeshUpdateFlags flags)
    {
      if (uvIndex < 0 || uvIndex > 7)
        throw new ArgumentOutOfRangeException(nameof (uvIndex), (object) uvIndex, "The uv index is invalid. Must be in the range 0 to 7.");
      this.SetSizedArrayForChannel(Mesh.GetUVChannel(uvIndex), VertexAttributeFormat.Float32, dim, uvs, NoAllocHelpers.SafeLength(uvs), arrayStart, arraySize, flags);
    }

    /// <summary>
    ///   <para>Sets the texture coordinates (UVs) stored in a given channel.</para>
    /// </summary>
    /// <param name="channel">The channel, in [0..7] range.</param>
    /// <param name="uvs">The UV data to set.</param>
    public void SetUVs(int channel, Vector2[] uvs)
    {
      this.SetUVs(channel, uvs, 0, NoAllocHelpers.SafeLength((Array) uvs));
    }

    /// <summary>
    ///   <para>Sets the texture coordinates (UVs) stored in a given channel.</para>
    /// </summary>
    /// <param name="channel">The channel, in [0..7] range.</param>
    /// <param name="uvs">The UV data to set.</param>
    public void SetUVs(int channel, Vector3[] uvs)
    {
      this.SetUVs(channel, uvs, 0, NoAllocHelpers.SafeLength((Array) uvs));
    }

    /// <summary>
    ///   <para>Sets the texture coordinates (UVs) stored in a given channel.</para>
    /// </summary>
    /// <param name="channel">The channel, in [0..7] range.</param>
    /// <param name="uvs">The UV data to set.</param>
    public void SetUVs(int channel, Vector4[] uvs)
    {
      this.SetUVs(channel, uvs, 0, NoAllocHelpers.SafeLength((Array) uvs));
    }

    /// <summary>
    ///   <para>Sets the UVs of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="channel">The UV channel, in [0..7] range.</param>
    /// <param name="uvs">UVs to set for the given index.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetUVs(int channel, Vector2[] uvs, int start, int length)
    {
      this.SetUVs(channel, uvs, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the UVs of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="channel">The UV channel, in [0..7] range.</param>
    /// <param name="uvs">UVs to set for the given index.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetUVs(int channel, Vector2[] uvs, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetUvsImpl(channel, 2, (Array) uvs, start, length, flags);
    }

    /// <summary>
    ///   <para>Sets the UVs of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="channel">The UV channel, in [0..7] range.</param>
    /// <param name="uvs">UVs to set for the given index.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetUVs(int channel, Vector3[] uvs, int start, int length)
    {
      this.SetUVs(channel, uvs, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the UVs of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="channel">The UV channel, in [0..7] range.</param>
    /// <param name="uvs">UVs to set for the given index.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetUVs(int channel, Vector3[] uvs, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetUvsImpl(channel, 3, (Array) uvs, start, length, flags);
    }

    /// <summary>
    ///   <para>Sets the UVs of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="channel">The UV channel, in [0..7] range.</param>
    /// <param name="uvs">UVs to set for the given index.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    [ExcludeFromDocs]
    public void SetUVs(int channel, Vector4[] uvs, int start, int length)
    {
      this.SetUVs(channel, uvs, start, length, MeshUpdateFlags.Default);
    }

    /// <summary>
    ///   <para>Sets the UVs of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="channel">The UV channel, in [0..7] range.</param>
    /// <param name="uvs">UVs to set for the given index.</param>
    /// <param name="start">Index of the first element to take from the input array.</param>
    /// <param name="length">Number of elements to take from the input array.</param>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetUVs(int channel, Vector4[] uvs, int start, int length, [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      this.SetUvsImpl(channel, 4, (Array) uvs, start, length, flags);
    }

    public void SetUVs<T>(int channel, NativeArray<T> uvs) where T : struct
    {
      this.SetUVs<T>(channel, uvs, 0, uvs.Length);
    }

    [ExcludeFromDocs]
    public void SetUVs<T>(int channel, NativeArray<T> uvs, int start, int length) where T : struct
    {
      this.SetUVs<T>(channel, uvs, start, length, MeshUpdateFlags.Default);
    }

    public unsafe void SetUVs<T>(
      int channel,
      NativeArray<T> uvs,
      int start,
      int length,
      [UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
      where T : struct
    {
      if (channel < 0 || channel > 7)
        throw new ArgumentOutOfRangeException(nameof (channel), (object) channel, "The uv index is invalid. Must be in the range 0 to 7.");
      int num = UnsafeUtility.SizeOf<T>();
      if ((num & 3) != 0)
        throw new ArgumentException("SetUVs with NativeArray should use struct type that is multiple of 4 bytes in size");
      int dim = num / 4;
      if (dim < 1 || dim > 4)
        throw new ArgumentException("SetUVs with NativeArray should use struct type that is 1..4 floats in size");
      this.SetSizedNativeArrayForChannel(Mesh.GetUVChannel(channel), VertexAttributeFormat.Float32, dim, (IntPtr) uvs.GetUnsafeReadOnlyPtr<T>(), uvs.Length, start, length, flags);
    }

    private void GetUVsImpl<T>(int uvIndex, List<T> uvs, int dim)
    {
      if (uvs == null)
        throw new ArgumentNullException(nameof (uvs), "The result uvs list cannot be null.");
      if (uvIndex < 0 || uvIndex > 7)
        throw new IndexOutOfRangeException("The uv index is invalid. Must be in the range 0 to 7.");
      this.GetListForChannel<T>(uvs, this.vertexCount, Mesh.GetUVChannel(uvIndex), dim);
    }

    public void GetUVs(int channel, List<Vector2> uvs) => this.GetUVsImpl<Vector2>(channel, uvs, 2);

    public void GetUVs(int channel, List<Vector3> uvs) => this.GetUVsImpl<Vector3>(channel, uvs, 3);

    public void GetUVs(int channel, List<Vector4> uvs) => this.GetUVsImpl<Vector4>(channel, uvs, 4);

    /// <summary>
    ///   <para>Returns the number of vertex attributes that the mesh has. (Read Only)</para>
    /// </summary>
    public int vertexAttributeCount => this.GetVertexAttributeCountImpl();

    /// <summary>
    ///   <para>Get information about vertex attributes of a Mesh.</para>
    /// </summary>
    /// <returns>
    ///   <para>Array of vertex attribute information.</para>
    /// </returns>
    public VertexAttributeDescriptor[] GetVertexAttributes()
    {
      return (VertexAttributeDescriptor[]) this.GetVertexAttributesAlloc();
    }

    /// <summary>
    ///   <para>Get information about vertex attributes of a Mesh, without memory allocations.</para>
    /// </summary>
    /// <param name="attributes">Collection of vertex attributes to receive the results.</param>
    /// <returns>
    ///   <para>The number of vertex attributes returned in the attributes container.</para>
    /// </returns>
    public int GetVertexAttributes(VertexAttributeDescriptor[] attributes)
    {
      return this.GetVertexAttributesArray(attributes);
    }

    public int GetVertexAttributes(List<VertexAttributeDescriptor> attributes)
    {
      return this.GetVertexAttributesList(attributes);
    }

    /// <summary>
    ///   <para>Sets the vertex buffer size and layout.</para>
    /// </summary>
    /// <param name="vertexCount">The number of vertices in the Mesh.</param>
    /// <param name="attributes">Layout of the vertex data -- which attributes are present, their data types and so on.</param>
    public void SetVertexBufferParams(
      int vertexCount,
      params VertexAttributeDescriptor[] attributes)
    {
      this.SetVertexBufferParamsFromArray(vertexCount, attributes);
    }

    public unsafe void SetVertexBufferParams(
      int vertexCount,
      NativeArray<VertexAttributeDescriptor> attributes)
    {
      this.SetVertexBufferParamsFromPtr(vertexCount, (IntPtr) attributes.GetUnsafeReadOnlyPtr<VertexAttributeDescriptor>(), attributes.Length);
    }

    public unsafe void SetVertexBufferData<T>(
      NativeArray<T> data,
      int dataStart,
      int meshBufferStart,
      int count,
      int stream = 0,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
      where T : struct
    {
      if (!this.canAccess)
        throw new InvalidOperationException("Not allowed to access vertex data on mesh '" + this.name + "' (isReadable is false; Read/Write must be enabled in import settings)");
      if (dataStart < 0 || meshBufferStart < 0 || count < 0 || dataStart + count > data.Length)
        throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (dataStart:{0} meshBufferStart:{1} count:{2})", (object) dataStart, (object) meshBufferStart, (object) count));
      this.InternalSetVertexBufferData(stream, (IntPtr) data.GetUnsafeReadOnlyPtr<T>(), dataStart, meshBufferStart, count, UnsafeUtility.SizeOf<T>(), flags);
    }

    public void SetVertexBufferData<T>(
      T[] data,
      int dataStart,
      int meshBufferStart,
      int count,
      int stream = 0,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
      where T : struct
    {
      if (!this.canAccess)
        throw new InvalidOperationException("Not allowed to access vertex data on mesh '" + this.name + "' (isReadable is false; Read/Write must be enabled in import settings)");
      if (!UnsafeUtility.IsArrayBlittable((Array) data))
        throw new ArgumentException("Array passed to SetVertexBufferData must be blittable.\n" + UnsafeUtility.GetReasonForArrayNonBlittable((Array) data));
      if (dataStart < 0 || meshBufferStart < 0 || count < 0 || dataStart + count > data.Length)
        throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (dataStart:{0} meshBufferStart:{1} count:{2})", (object) dataStart, (object) meshBufferStart, (object) count));
      this.InternalSetVertexBufferDataFromArray(stream, (Array) data, dataStart, meshBufferStart, count, UnsafeUtility.SizeOf<T>(), flags);
    }

    public void SetVertexBufferData<T>(
      List<T> data,
      int dataStart,
      int meshBufferStart,
      int count,
      int stream = 0,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
      where T : struct
    {
      if (!this.canAccess)
        throw new InvalidOperationException("Not allowed to access vertex data on mesh '" + this.name + "' (isReadable is false; Read/Write must be enabled in import settings)");
      if (!UnsafeUtility.IsGenericListBlittable<T>())
        throw new ArgumentException(string.Format("List<{0}> passed to {1} must be blittable.\n{2}", (object) typeof (T), (object) nameof (SetVertexBufferData), (object) UnsafeUtility.GetReasonForGenericListNonBlittable<T>()));
      if (dataStart < 0 || meshBufferStart < 0 || count < 0 || dataStart + count > data.Count)
        throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (dataStart:{0} meshBufferStart:{1} count:{2})", (object) dataStart, (object) meshBufferStart, (object) count));
      this.InternalSetVertexBufferDataFromArray(stream, NoAllocHelpers.ExtractArrayFromList((object) data), dataStart, meshBufferStart, count, UnsafeUtility.SizeOf<T>(), flags);
    }

    /// <summary>
    ///   <para>Gets a snapshot of Mesh data for read-only access.</para>
    /// </summary>
    /// <param name="mesh">The input mesh.</param>
    /// <param name="meshes">The input meshes.</param>
    /// <returns>
    ///   <para>Returns a MeshDataArray containing read-only MeshData structs. See Mesh.MeshDataArray and Mesh.MeshData.</para>
    /// </returns>
    public static Mesh.MeshDataArray AcquireReadOnlyMeshData(Mesh mesh)
    {
      return new Mesh.MeshDataArray(mesh);
    }

    /// <summary>
    ///   <para>Gets a snapshot of Mesh data for read-only access.</para>
    /// </summary>
    /// <param name="mesh">The input mesh.</param>
    /// <param name="meshes">The input meshes.</param>
    /// <returns>
    ///   <para>Returns a MeshDataArray containing read-only MeshData structs. See Mesh.MeshDataArray and Mesh.MeshData.</para>
    /// </returns>
    public static Mesh.MeshDataArray AcquireReadOnlyMeshData(Mesh[] meshes)
    {
      return meshes != null ? new Mesh.MeshDataArray(meshes, meshes.Length) : throw new ArgumentNullException(nameof (meshes), "Mesh array is null");
    }

    public static Mesh.MeshDataArray AcquireReadOnlyMeshData(List<Mesh> meshes)
    {
      return meshes != null ? new Mesh.MeshDataArray(NoAllocHelpers.ExtractArrayFromListT<Mesh>(meshes), meshes.Count) : throw new ArgumentNullException(nameof (meshes), "Mesh list is null");
    }

    /// <summary>
    ///   <para>Allocates data structures for Mesh creation using C# Jobs.</para>
    /// </summary>
    /// <param name="meshCount">The amount of meshes that will be created.</param>
    /// <returns>
    ///   <para>Returns a MeshDataArray containing writeable MeshData structs. See Mesh.MeshDataArray and Mesh.MeshData.</para>
    /// </returns>
    public static Mesh.MeshDataArray AllocateWritableMeshData(int meshCount)
    {
      return new Mesh.MeshDataArray(meshCount);
    }

    public static void ApplyAndDisposeWritableMeshData(
      Mesh.MeshDataArray data,
      Mesh mesh,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      if ((Object) mesh == (Object) null)
        throw new ArgumentNullException(nameof (mesh), "Mesh is null");
      if (data.Length != 1)
        throw new InvalidOperationException(string.Format("{0} length must be 1 to apply to one mesh, was {1}", (object) "MeshDataArray", (object) data.Length));
      data.ApplyToMeshAndDispose(mesh, flags);
    }

    public static void ApplyAndDisposeWritableMeshData(
      Mesh.MeshDataArray data,
      Mesh[] meshes,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      if (meshes == null)
        throw new ArgumentNullException(nameof (meshes), "Mesh array is null");
      if (data.Length != meshes.Length)
        throw new InvalidOperationException(string.Format("{0} length ({1}) must match destination meshes array length ({2})", (object) "MeshDataArray", (object) data.Length, (object) meshes.Length));
      data.ApplyToMeshesAndDispose(meshes, flags);
    }

    public static void ApplyAndDisposeWritableMeshData(
      Mesh.MeshDataArray data,
      List<Mesh> meshes,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      if (meshes == null)
        throw new ArgumentNullException(nameof (meshes), "Mesh list is null");
      if (data.Length != meshes.Count)
        throw new InvalidOperationException(string.Format("{0} length ({1}) must match destination meshes list length ({2})", (object) "MeshDataArray", (object) data.Length, (object) meshes.Count));
      data.ApplyToMeshesAndDispose(NoAllocHelpers.ExtractArrayFromListT<Mesh>(meshes), flags);
    }

    /// <summary>
    ///   <para>Retrieves a GraphicsBuffer that provides direct acces to the GPU vertex buffer.</para>
    /// </summary>
    /// <param name="index">Vertex data stream index to get the buffer for.</param>
    /// <returns>
    ///   <para>The mesh vertex buffer as a GraphicsBuffer.</para>
    /// </returns>
    public GraphicsBuffer GetVertexBuffer(int index)
    {
      if ((Object) this == (Object) null)
        throw new NullReferenceException();
      GraphicsBuffer vertexBufferImpl = this.GetVertexBufferImpl(index);
      vertexBufferImpl?.AddBufferToLeakDetector();
      return vertexBufferImpl;
    }

    /// <summary>
    ///   <para>Retrieves a GraphicsBuffer to the GPU index buffer.</para>
    /// </summary>
    /// <returns>
    ///   <para>The mesh index buffer as a GraphicsBuffer.</para>
    /// </returns>
    public GraphicsBuffer GetIndexBuffer()
    {
      if ((Object) this == (Object) null)
        throw new NullReferenceException();
      GraphicsBuffer indexBufferImpl = this.GetIndexBufferImpl();
      indexBufferImpl?.AddBufferToLeakDetector();
      return indexBufferImpl;
    }

    private void PrintErrorCantAccessIndices()
    {
      Debug.LogError((object) string.Format("Not allowed to access triangles/indices on mesh '{0}' (isReadable is false; Read/Write must be enabled in import settings)", (object) this.name));
    }

    private bool CheckCanAccessSubmesh(int submesh, bool errorAboutTriangles)
    {
      if (!this.canAccess)
      {
        this.PrintErrorCantAccessIndices();
        return false;
      }
      if (submesh >= 0 && submesh < this.subMeshCount)
        return true;
      Debug.LogError((object) string.Format("Failed getting {0}. Submesh index is out of bounds.", errorAboutTriangles ? (object) "triangles" : (object) "indices"), (Object) this);
      return false;
    }

    private bool CheckCanAccessSubmeshTriangles(int submesh)
    {
      return this.CheckCanAccessSubmesh(submesh, true);
    }

    private bool CheckCanAccessSubmeshIndices(int submesh)
    {
      return this.CheckCanAccessSubmesh(submesh, false);
    }

    /// <summary>
    ///   <para>An array containing all triangles in the Mesh.</para>
    /// </summary>
    public int[] triangles
    {
      get
      {
        if (this.canAccess)
          return this.GetTrianglesImpl(-1, true);
        this.PrintErrorCantAccessIndices();
        return new int[0];
      }
      set
      {
        if (this.canAccess)
          this.SetTrianglesImpl(-1, IndexFormat.UInt32, (Array) value, NoAllocHelpers.SafeLength((Array) value), 0, NoAllocHelpers.SafeLength((Array) value), true, 0);
        else
          this.PrintErrorCantAccessIndices();
      }
    }

    /// <summary>
    ///   <para>Fetches the triangle list for the specified sub-mesh on this object.</para>
    /// </summary>
    /// <param name="triangles">A list of vertex indices to populate. Any existing items in the list are replaced.</param>
    /// <param name="submesh">The sub-mesh index. See subMeshCount.</param>
    /// <param name="applyBaseVertex">True (default value) will apply base vertex offset to returned indices.</param>
    public int[] GetTriangles(int submesh) => this.GetTriangles(submesh, true);

    /// <summary>
    ///   <para>Fetches the triangle list for the specified sub-mesh on this object.</para>
    /// </summary>
    /// <param name="triangles">A list of vertex indices to populate. Any existing items in the list are replaced.</param>
    /// <param name="submesh">The sub-mesh index. See subMeshCount.</param>
    /// <param name="applyBaseVertex">True (default value) will apply base vertex offset to returned indices.</param>
    public int[] GetTriangles(int submesh, [UnityEngine.Internal.DefaultValue("true")] bool applyBaseVertex)
    {
      return this.CheckCanAccessSubmeshTriangles(submesh) ? this.GetTrianglesImpl(submesh, applyBaseVertex) : new int[0];
    }

    public void GetTriangles(List<int> triangles, int submesh)
    {
      this.GetTriangles(triangles, submesh, true);
    }

    public void GetTriangles(List<int> triangles, int submesh, [UnityEngine.Internal.DefaultValue("true")] bool applyBaseVertex)
    {
      if (triangles == null)
        throw new ArgumentNullException(nameof (triangles), "The result triangles list cannot be null.");
      if (submesh < 0 || submesh >= this.subMeshCount)
        throw new IndexOutOfRangeException("Specified sub mesh is out of range. Must be greater or equal to 0 and less than subMeshCount.");
      NoAllocHelpers.EnsureListElemCount<int>(triangles, 3 * (int) this.GetTrianglesCountImpl(submesh));
      this.GetTrianglesNonAllocImpl(NoAllocHelpers.ExtractArrayFromListT<int>(triangles), submesh, applyBaseVertex);
    }

    public void GetTriangles(List<ushort> triangles, int submesh, bool applyBaseVertex = true)
    {
      if (triangles == null)
        throw new ArgumentNullException(nameof (triangles), "The result triangles list cannot be null.");
      if (submesh < 0 || submesh >= this.subMeshCount)
        throw new IndexOutOfRangeException("Specified sub mesh is out of range. Must be greater or equal to 0 and less than subMeshCount.");
      NoAllocHelpers.EnsureListElemCount<ushort>(triangles, 3 * (int) this.GetTrianglesCountImpl(submesh));
      this.GetTrianglesNonAllocImpl16(NoAllocHelpers.ExtractArrayFromListT<ushort>(triangles), submesh, applyBaseVertex);
    }

    /// <summary>
    ///   <para>Fetches the index list for the specified sub-mesh.</para>
    /// </summary>
    /// <param name="submesh">The sub-mesh index. See subMeshCount.</param>
    /// <param name="applyBaseVertex">True (default value) will apply base vertex offset to returned indices.</param>
    /// <returns>
    ///   <para>Array with face indices.</para>
    /// </returns>
    [ExcludeFromDocs]
    public int[] GetIndices(int submesh) => this.GetIndices(submesh, true);

    /// <summary>
    ///   <para>Fetches the index list for the specified sub-mesh.</para>
    /// </summary>
    /// <param name="submesh">The sub-mesh index. See subMeshCount.</param>
    /// <param name="applyBaseVertex">True (default value) will apply base vertex offset to returned indices.</param>
    /// <returns>
    ///   <para>Array with face indices.</para>
    /// </returns>
    public int[] GetIndices(int submesh, [UnityEngine.Internal.DefaultValue("true")] bool applyBaseVertex)
    {
      return this.CheckCanAccessSubmeshIndices(submesh) ? this.GetIndicesImpl(submesh, applyBaseVertex) : new int[0];
    }

    [ExcludeFromDocs]
    public void GetIndices(List<int> indices, int submesh)
    {
      this.GetIndices(indices, submesh, true);
    }

    public void GetIndices(List<int> indices, int submesh, [UnityEngine.Internal.DefaultValue("true")] bool applyBaseVertex)
    {
      if (indices == null)
        throw new ArgumentNullException(nameof (indices), "The result indices list cannot be null.");
      if (submesh < 0 || submesh >= this.subMeshCount)
        throw new IndexOutOfRangeException("Specified sub mesh is out of range. Must be greater or equal to 0 and less than subMeshCount.");
      NoAllocHelpers.EnsureListElemCount<int>(indices, (int) this.GetIndexCount(submesh));
      this.GetIndicesNonAllocImpl(NoAllocHelpers.ExtractArrayFromListT<int>(indices), submesh, applyBaseVertex);
    }

    public void GetIndices(List<ushort> indices, int submesh, bool applyBaseVertex = true)
    {
      if (indices == null)
        throw new ArgumentNullException(nameof (indices), "The result indices list cannot be null.");
      if (submesh < 0 || submesh >= this.subMeshCount)
        throw new IndexOutOfRangeException("Specified sub mesh is out of range. Must be greater or equal to 0 and less than subMeshCount.");
      NoAllocHelpers.EnsureListElemCount<ushort>(indices, (int) this.GetIndexCount(submesh));
      this.GetIndicesNonAllocImpl16(NoAllocHelpers.ExtractArrayFromListT<ushort>(indices), submesh, applyBaseVertex);
    }

    public unsafe void SetIndexBufferData<T>(
      NativeArray<T> data,
      int dataStart,
      int meshBufferStart,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
      where T : struct
    {
      if (!this.canAccess)
      {
        this.PrintErrorCantAccessIndices();
      }
      else
      {
        if (dataStart < 0 || meshBufferStart < 0 || count < 0 || dataStart + count > data.Length)
          throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (dataStart:{0} meshBufferStart:{1} count:{2})", (object) dataStart, (object) meshBufferStart, (object) count));
        this.InternalSetIndexBufferData((IntPtr) data.GetUnsafeReadOnlyPtr<T>(), dataStart, meshBufferStart, count, UnsafeUtility.SizeOf<T>(), flags);
      }
    }

    public void SetIndexBufferData<T>(
      T[] data,
      int dataStart,
      int meshBufferStart,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
      where T : struct
    {
      if (!this.canAccess)
      {
        this.PrintErrorCantAccessIndices();
      }
      else
      {
        if (!UnsafeUtility.IsArrayBlittable((Array) data))
          throw new ArgumentException("Array passed to SetIndexBufferData must be blittable.\n" + UnsafeUtility.GetReasonForArrayNonBlittable((Array) data));
        if (dataStart < 0 || meshBufferStart < 0 || count < 0 || dataStart + count > data.Length)
          throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (dataStart:{0} meshBufferStart:{1} count:{2})", (object) dataStart, (object) meshBufferStart, (object) count));
        this.InternalSetIndexBufferDataFromArray((Array) data, dataStart, meshBufferStart, count, UnsafeUtility.SizeOf<T>(), flags);
      }
    }

    public void SetIndexBufferData<T>(
      List<T> data,
      int dataStart,
      int meshBufferStart,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
      where T : struct
    {
      if (!this.canAccess)
      {
        this.PrintErrorCantAccessIndices();
      }
      else
      {
        if (!UnsafeUtility.IsGenericListBlittable<T>())
          throw new ArgumentException(string.Format("List<{0}> passed to {1} must be blittable.\n{2}", (object) typeof (T), (object) nameof (SetIndexBufferData), (object) UnsafeUtility.GetReasonForGenericListNonBlittable<T>()));
        if (dataStart < 0 || meshBufferStart < 0 || count < 0 || dataStart + count > data.Count)
          throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (dataStart:{0} meshBufferStart:{1} count:{2})", (object) dataStart, (object) meshBufferStart, (object) count));
        this.InternalSetIndexBufferDataFromArray(NoAllocHelpers.ExtractArrayFromList((object) data), dataStart, meshBufferStart, count, UnsafeUtility.SizeOf<T>(), flags);
      }
    }

    /// <summary>
    ///   <para>Gets the starting index location within the Mesh's index buffer, for the given sub-mesh.</para>
    /// </summary>
    /// <param name="submesh"></param>
    public uint GetIndexStart(int submesh)
    {
      return submesh >= 0 && submesh < this.subMeshCount ? this.GetIndexStartImpl(submesh) : throw new IndexOutOfRangeException("Specified sub mesh is out of range. Must be greater or equal to 0 and less than subMeshCount.");
    }

    /// <summary>
    ///   <para>Gets the index count of the given sub-mesh.</para>
    /// </summary>
    /// <param name="submesh"></param>
    public uint GetIndexCount(int submesh)
    {
      return submesh >= 0 && submesh < this.subMeshCount ? this.GetIndexCountImpl(submesh) : throw new IndexOutOfRangeException("Specified sub mesh is out of range. Must be greater or equal to 0 and less than subMeshCount.");
    }

    /// <summary>
    ///   <para>Gets the base vertex index of the given sub-mesh.</para>
    /// </summary>
    /// <param name="submesh">The sub-mesh index. See subMeshCount.</param>
    /// <returns>
    ///   <para>The offset applied to all vertex indices of this sub-mesh.</para>
    /// </returns>
    public uint GetBaseVertex(int submesh)
    {
      return submesh >= 0 && submesh < this.subMeshCount ? this.GetBaseVertexImpl(submesh) : throw new IndexOutOfRangeException("Specified sub mesh is out of range. Must be greater or equal to 0 and less than subMeshCount.");
    }

    private void CheckIndicesArrayRange(int valuesLength, int start, int length)
    {
      if (start < 0)
        throw new ArgumentOutOfRangeException(nameof (start), (object) start, "Mesh indices array start can't be negative.");
      if (length < 0)
        throw new ArgumentOutOfRangeException(nameof (length), (object) length, "Mesh indices array length can't be negative.");
      if (start >= valuesLength && length != 0)
        throw new ArgumentOutOfRangeException(nameof (start), (object) start, "Mesh indices array start is outside of array size.");
      if (start + length > valuesLength)
        throw new ArgumentOutOfRangeException(nameof (length), (object) (start + length), "Mesh indices array start+count is outside of array size.");
    }

    private void SetTrianglesImpl(
      int submesh,
      IndexFormat indicesFormat,
      Array triangles,
      int trianglesArrayLength,
      int start,
      int length,
      bool calculateBounds,
      int baseVertex)
    {
      this.CheckIndicesArrayRange(trianglesArrayLength, start, length);
      this.SetIndicesImpl(submesh, MeshTopology.Triangles, indicesFormat, triangles, start, length, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the triangle list for the sub-mesh.</para>
    /// </summary>
    /// <param name="triangles">The list of indices that define the triangles.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the triangles. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the triangles.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all triangle vertex indices.</param>
    [ExcludeFromDocs]
    public void SetTriangles(int[] triangles, int submesh)
    {
      this.SetTriangles(triangles, submesh, true, 0);
    }

    /// <summary>
    ///   <para>Sets the triangle list for the sub-mesh.</para>
    /// </summary>
    /// <param name="triangles">The list of indices that define the triangles.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the triangles. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the triangles.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all triangle vertex indices.</param>
    [ExcludeFromDocs]
    public void SetTriangles(int[] triangles, int submesh, bool calculateBounds)
    {
      this.SetTriangles(triangles, submesh, calculateBounds, 0);
    }

    /// <summary>
    ///   <para>Sets the triangle list for the sub-mesh.</para>
    /// </summary>
    /// <param name="triangles">The list of indices that define the triangles.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the triangles. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the triangles.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all triangle vertex indices.</param>
    public void SetTriangles(int[] triangles, int submesh, [UnityEngine.Internal.DefaultValue("true")] bool calculateBounds, [UnityEngine.Internal.DefaultValue("0")] int baseVertex)
    {
      this.SetTriangles(triangles, 0, NoAllocHelpers.SafeLength((Array) triangles), submesh, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the triangle list of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="triangles">The list of indices that define the triangles.</param>
    /// <param name="trianglesStart">Index of the first element to take from the input array.</param>
    /// <param name="trianglesLength">Number of elements to take from the input array.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the triangles. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the triangles.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all triangle vertex indices.</param>
    public void SetTriangles(
      int[] triangles,
      int trianglesStart,
      int trianglesLength,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshTriangles(submesh))
        return;
      this.SetTrianglesImpl(submesh, IndexFormat.UInt32, (Array) triangles, NoAllocHelpers.SafeLength((Array) triangles), trianglesStart, trianglesLength, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the triangle list for the sub-mesh.</para>
    /// </summary>
    /// <param name="triangles">The list of indices that define the triangles.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the triangles. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the triangles.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all triangle vertex indices.</param>
    public void SetTriangles(
      ushort[] triangles,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      this.SetTriangles(triangles, 0, NoAllocHelpers.SafeLength((Array) triangles), submesh, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the triangle list of the Mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="triangles">The list of indices that define the triangles.</param>
    /// <param name="trianglesStart">Index of the first element to take from the input array.</param>
    /// <param name="trianglesLength">Number of elements to take from the input array.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the triangles. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the triangles.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all triangle vertex indices.</param>
    public void SetTriangles(
      ushort[] triangles,
      int trianglesStart,
      int trianglesLength,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshTriangles(submesh))
        return;
      this.SetTrianglesImpl(submesh, IndexFormat.UInt16, (Array) triangles, NoAllocHelpers.SafeLength((Array) triangles), trianglesStart, trianglesLength, calculateBounds, baseVertex);
    }

    [ExcludeFromDocs]
    public void SetTriangles(List<int> triangles, int submesh)
    {
      this.SetTriangles(triangles, submesh, true, 0);
    }

    [ExcludeFromDocs]
    public void SetTriangles(List<int> triangles, int submesh, bool calculateBounds)
    {
      this.SetTriangles(triangles, submesh, calculateBounds, 0);
    }

    public void SetTriangles(
      List<int> triangles,
      int submesh,
      [UnityEngine.Internal.DefaultValue("true")] bool calculateBounds,
      [UnityEngine.Internal.DefaultValue("0")] int baseVertex)
    {
      this.SetTriangles(triangles, 0, NoAllocHelpers.SafeLength<int>(triangles), submesh, calculateBounds, baseVertex);
    }

    public void SetTriangles(
      List<int> triangles,
      int trianglesStart,
      int trianglesLength,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshTriangles(submesh))
        return;
      this.SetTrianglesImpl(submesh, IndexFormat.UInt32, NoAllocHelpers.ExtractArrayFromList((object) triangles), NoAllocHelpers.SafeLength<int>(triangles), trianglesStart, trianglesLength, calculateBounds, baseVertex);
    }

    public void SetTriangles(
      List<ushort> triangles,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      this.SetTriangles(triangles, 0, NoAllocHelpers.SafeLength<ushort>(triangles), submesh, calculateBounds, baseVertex);
    }

    public void SetTriangles(
      List<ushort> triangles,
      int trianglesStart,
      int trianglesLength,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshTriangles(submesh))
        return;
      this.SetTrianglesImpl(submesh, IndexFormat.UInt16, NoAllocHelpers.ExtractArrayFromList((object) triangles), NoAllocHelpers.SafeLength<ushort>(triangles), trianglesStart, trianglesLength, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the index buffer for the sub-mesh.</para>
    /// </summary>
    /// <param name="indices">The array of indices that define the mesh faces.</param>
    /// <param name="topology">The topology of the Mesh, e.g: Triangles, Lines, Quads, Points, etc. See MeshTopology.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the indices. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the indices.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all vertex indices.</param>
    [ExcludeFromDocs]
    public void SetIndices(int[] indices, MeshTopology topology, int submesh)
    {
      this.SetIndices(indices, topology, submesh, true, 0);
    }

    /// <summary>
    ///   <para>Sets the index buffer for the sub-mesh.</para>
    /// </summary>
    /// <param name="indices">The array of indices that define the mesh faces.</param>
    /// <param name="topology">The topology of the Mesh, e.g: Triangles, Lines, Quads, Points, etc. See MeshTopology.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the indices. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the indices.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all vertex indices.</param>
    [ExcludeFromDocs]
    public void SetIndices(
      int[] indices,
      MeshTopology topology,
      int submesh,
      bool calculateBounds)
    {
      this.SetIndices(indices, topology, submesh, calculateBounds, 0);
    }

    /// <summary>
    ///   <para>Sets the index buffer for the sub-mesh.</para>
    /// </summary>
    /// <param name="indices">The array of indices that define the mesh faces.</param>
    /// <param name="topology">The topology of the Mesh, e.g: Triangles, Lines, Quads, Points, etc. See MeshTopology.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the indices. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the indices.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all vertex indices.</param>
    public void SetIndices(
      int[] indices,
      MeshTopology topology,
      int submesh,
      [UnityEngine.Internal.DefaultValue("true")] bool calculateBounds,
      [UnityEngine.Internal.DefaultValue("0")] int baseVertex)
    {
      this.SetIndices(indices, 0, NoAllocHelpers.SafeLength((Array) indices), topology, submesh, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the index buffer of a sub-mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="indices">The array of indices that define the mesh faces.</param>
    /// <param name="indicesStart">Index of the first element to take from the input array.</param>
    /// <param name="indicesLength">Number of elements to take from the input array.</param>
    /// <param name="topology">The topology of the Mesh, e.g: Triangles, Lines, Quads, Points, etc. See MeshTopology.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the indices. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the indices.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all vertex indices.</param>
    public void SetIndices(
      int[] indices,
      int indicesStart,
      int indicesLength,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshIndices(submesh))
        return;
      this.CheckIndicesArrayRange(NoAllocHelpers.SafeLength((Array) indices), indicesStart, indicesLength);
      this.SetIndicesImpl(submesh, topology, IndexFormat.UInt32, (Array) indices, indicesStart, indicesLength, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the index buffer for the sub-mesh.</para>
    /// </summary>
    /// <param name="indices">The array of indices that define the mesh faces.</param>
    /// <param name="topology">The topology of the Mesh, e.g: Triangles, Lines, Quads, Points, etc. See MeshTopology.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the indices. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the indices.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all vertex indices.</param>
    public void SetIndices(
      ushort[] indices,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      this.SetIndices(indices, 0, NoAllocHelpers.SafeLength((Array) indices), topology, submesh, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets the index buffer of a sub-mesh, using a part of the input array.</para>
    /// </summary>
    /// <param name="indices">The array of indices that define the mesh faces.</param>
    /// <param name="indicesStart">Index of the first element to take from the input array.</param>
    /// <param name="indicesLength">Number of elements to take from the input array.</param>
    /// <param name="topology">The topology of the Mesh, e.g: Triangles, Lines, Quads, Points, etc. See MeshTopology.</param>
    /// <param name="submesh">The sub-mesh to modify.</param>
    /// <param name="calculateBounds">Calculate the bounding box of the Mesh after setting the indices. This is done by default.
    /// Use false when you want to use the existing bounding box and reduce the CPU cost of setting the indices.</param>
    /// <param name="baseVertex">Optional vertex offset that is added to all vertex indices.</param>
    public void SetIndices(
      ushort[] indices,
      int indicesStart,
      int indicesLength,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshIndices(submesh))
        return;
      this.CheckIndicesArrayRange(NoAllocHelpers.SafeLength((Array) indices), indicesStart, indicesLength);
      this.SetIndicesImpl(submesh, topology, IndexFormat.UInt16, (Array) indices, indicesStart, indicesLength, calculateBounds, baseVertex);
    }

    public void SetIndices<T>(
      NativeArray<T> indices,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
      where T : struct
    {
      this.SetIndices<T>(indices, 0, indices.Length, topology, submesh, calculateBounds, baseVertex);
    }

    public unsafe void SetIndices<T>(
      NativeArray<T> indices,
      int indicesStart,
      int indicesLength,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
      where T : struct
    {
      if (!this.CheckCanAccessSubmeshIndices(submesh))
        return;
      int num = UnsafeUtility.SizeOf<T>();
      if (num != 2 && num != 4)
        throw new ArgumentException("SetIndices with NativeArray should use type is 2 or 4 bytes in size");
      this.CheckIndicesArrayRange(indices.Length, indicesStart, indicesLength);
      this.SetIndicesNativeArrayImpl(submesh, topology, num == 2 ? IndexFormat.UInt16 : IndexFormat.UInt32, (IntPtr) indices.GetUnsafeReadOnlyPtr<T>(), indicesStart, indicesLength, calculateBounds, baseVertex);
    }

    public void SetIndices(
      List<int> indices,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      this.SetIndices(indices, 0, NoAllocHelpers.SafeLength<int>(indices), topology, submesh, calculateBounds, baseVertex);
    }

    public void SetIndices(
      List<int> indices,
      int indicesStart,
      int indicesLength,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshIndices(submesh))
        return;
      Array arrayFromList = NoAllocHelpers.ExtractArrayFromList((object) indices);
      this.CheckIndicesArrayRange(NoAllocHelpers.SafeLength<int>(indices), indicesStart, indicesLength);
      this.SetIndicesImpl(submesh, topology, IndexFormat.UInt32, arrayFromList, indicesStart, indicesLength, calculateBounds, baseVertex);
    }

    public void SetIndices(
      List<ushort> indices,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      this.SetIndices(indices, 0, NoAllocHelpers.SafeLength<ushort>(indices), topology, submesh, calculateBounds, baseVertex);
    }

    public void SetIndices(
      List<ushort> indices,
      int indicesStart,
      int indicesLength,
      MeshTopology topology,
      int submesh,
      bool calculateBounds = true,
      int baseVertex = 0)
    {
      if (!this.CheckCanAccessSubmeshIndices(submesh))
        return;
      Array arrayFromList = NoAllocHelpers.ExtractArrayFromList((object) indices);
      this.CheckIndicesArrayRange(NoAllocHelpers.SafeLength<ushort>(indices), indicesStart, indicesLength);
      this.SetIndicesImpl(submesh, topology, IndexFormat.UInt16, arrayFromList, indicesStart, indicesLength, calculateBounds, baseVertex);
    }

    /// <summary>
    ///   <para>Sets information defining all sub-meshes in this Mesh, replacing any existing sub-meshes.</para>
    /// </summary>
    /// <param name="desc">An array or list of sub-mesh data descriptors.</param>
    /// <param name="start">Index of the first element to take from the array or list in desc.</param>
    /// <param name="count">Number of elements to take from the array or list in desc.</param>
    /// <param name="flags">(Optional) Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetSubMeshes(
      SubMeshDescriptor[] desc,
      int start,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      if (count > 0 && desc == null)
        throw new ArgumentNullException(nameof (desc), "Array of submeshes cannot be null unless count is zero.");
      int length = desc != null ? desc.Length : 0;
      if (start < 0 || count < 0 || start + count > length)
        throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (start:{0} count:{1} desc.Length:{2})", (object) start, (object) count, (object) length));
      for (int index = start; index < start + count; ++index)
      {
        MeshTopology topology = desc[index].topology;
        if (topology < MeshTopology.Triangles || topology > MeshTopology.Points)
          throw new ArgumentException(nameof (desc), string.Format("{0}-th submesh descriptor has invalid topology ({1}).", (object) index, (object) (int) topology));
        if (topology == (MeshTopology) 1)
          throw new ArgumentException(nameof (desc), string.Format("{0}-th submesh descriptor has triangles strip topology, which is no longer supported.", (object) index));
      }
      this.SetAllSubMeshesAtOnceFromArray(desc, start, count, flags);
    }

    /// <summary>
    ///   <para>Sets information defining all sub-meshes in this Mesh, replacing any existing sub-meshes.</para>
    /// </summary>
    /// <param name="desc">An array or list of sub-mesh data descriptors.</param>
    /// <param name="start">Index of the first element to take from the array or list in desc.</param>
    /// <param name="count">Number of elements to take from the array or list in desc.</param>
    /// <param name="flags">(Optional) Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void SetSubMeshes(SubMeshDescriptor[] desc, MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      this.SetSubMeshes(desc, 0, desc != null ? desc.Length : 0, flags);
    }

    public void SetSubMeshes(
      List<SubMeshDescriptor> desc,
      int start,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      this.SetSubMeshes(NoAllocHelpers.ExtractArrayFromListT<SubMeshDescriptor>(desc), start, count, flags);
    }

    public void SetSubMeshes(List<SubMeshDescriptor> desc, MeshUpdateFlags flags = MeshUpdateFlags.Default)
    {
      // ISSUE: explicit non-virtual call
      this.SetSubMeshes(NoAllocHelpers.ExtractArrayFromListT<SubMeshDescriptor>(desc), 0, desc != null ? __nonvirtual (desc.Count) : 0, flags);
    }

    public unsafe void SetSubMeshes<T>(
      NativeArray<T> desc,
      int start,
      int count,
      MeshUpdateFlags flags = MeshUpdateFlags.Default)
      where T : struct
    {
      if (UnsafeUtility.SizeOf<T>() != UnsafeUtility.SizeOf<SubMeshDescriptor>())
        throw new ArgumentException(string.Format("{0} with NativeArray should use struct type that is {1} bytes in size", (object) nameof (SetSubMeshes), (object) UnsafeUtility.SizeOf<SubMeshDescriptor>()));
      if (start < 0 || count < 0 || start + count > desc.Length)
        throw new ArgumentOutOfRangeException(string.Format("Bad start/count arguments (start:{0} count:{1} desc.Length:{2})", (object) start, (object) count, (object) desc.Length));
      this.SetAllSubMeshesAtOnceFromNativeArray((IntPtr) desc.GetUnsafeReadOnlyPtr<T>(), start, count, flags);
    }

    public void SetSubMeshes<T>(NativeArray<T> desc, MeshUpdateFlags flags = MeshUpdateFlags.Default) where T : struct
    {
      this.SetSubMeshes<T>(desc, 0, desc.Length, flags);
    }

    public void GetBindposes(List<Matrix4x4> bindposes)
    {
      if (bindposes == null)
        throw new ArgumentNullException(nameof (bindposes), "The result bindposes list cannot be null.");
      NoAllocHelpers.EnsureListElemCount<Matrix4x4>(bindposes, this.GetBindposeCount());
      this.GetBindposesNonAllocImpl(NoAllocHelpers.ExtractArrayFromListT<Matrix4x4>(bindposes));
    }

    public void GetBoneWeights(List<BoneWeight> boneWeights)
    {
      if (boneWeights == null)
        throw new ArgumentNullException(nameof (boneWeights), "The result boneWeights list cannot be null.");
      if (this.HasBoneWeights())
        NoAllocHelpers.EnsureListElemCount<BoneWeight>(boneWeights, this.vertexCount);
      this.GetBoneWeightsNonAllocImpl(NoAllocHelpers.ExtractArrayFromListT<BoneWeight>(boneWeights));
    }

    /// <summary>
    ///   <para>The BoneWeight for each vertex in the Mesh, which represents 4 bones per vertex.</para>
    /// </summary>
    public BoneWeight[] boneWeights
    {
      get => this.GetBoneWeightsImpl();
      set => this.SetBoneWeightsImpl(value);
    }

    /// <summary>
    ///   <para>Clears all vertex data and all triangle indices.</para>
    /// </summary>
    /// <param name="keepVertexLayout">True if the existing Mesh data layout should be preserved.</param>
    public void Clear([UnityEngine.Internal.DefaultValue("true")] bool keepVertexLayout)
    {
      this.ClearImpl(keepVertexLayout);
    }

    [ExcludeFromDocs]
    public void Clear() => this.ClearImpl(true);

    [ExcludeFromDocs]
    public void RecalculateBounds() => this.RecalculateBounds(MeshUpdateFlags.Default);

    [ExcludeFromDocs]
    public void RecalculateNormals() => this.RecalculateNormals(MeshUpdateFlags.Default);

    [ExcludeFromDocs]
    public void RecalculateTangents() => this.RecalculateTangents(MeshUpdateFlags.Default);

    /// <summary>
    ///   <para>Recalculate the bounding volume of the Mesh from the vertices.</para>
    /// </summary>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void RecalculateBounds([UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      if (this.canAccess)
        this.RecalculateBoundsImpl(flags);
      else
        Debug.LogError((object) string.Format("Not allowed to call RecalculateBounds() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Recalculates the normals of the Mesh from the triangles and vertices.</para>
    /// </summary>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void RecalculateNormals([UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      if (this.canAccess)
        this.RecalculateNormalsImpl(flags);
      else
        Debug.LogError((object) string.Format("Not allowed to call RecalculateNormals() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Recalculates the tangents of the Mesh from the normals and texture coordinates.</para>
    /// </summary>
    /// <param name="flags">Flags controlling the function behavior, see MeshUpdateFlags.</param>
    public void RecalculateTangents([UnityEngine.Internal.DefaultValue("MeshUpdateFlags.Default")] MeshUpdateFlags flags)
    {
      if (this.canAccess)
        this.RecalculateTangentsImpl(flags);
      else
        Debug.LogError((object) string.Format("Not allowed to call RecalculateTangents() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Recalculates the UV distribution metric of the Mesh from the vertices and uv coordinates.</para>
    /// </summary>
    /// <param name="uvSetIndex">The UV set index to set the UV distibution metric for. Use 0 for first index.</param>
    /// <param name="uvAreaThreshold">The minimum UV area to consider. The default value is 1e-9f.</param>
    public void RecalculateUVDistributionMetric(int uvSetIndex, float uvAreaThreshold = 1E-09f)
    {
      if (this.canAccess)
        this.RecalculateUVDistributionMetricImpl(uvSetIndex, uvAreaThreshold);
      else
        Debug.LogError((object) string.Format("Not allowed to call RecalculateUVDistributionMetric() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Recalculates the UV distribution metrics of the Mesh from the vertices and uv coordinates.</para>
    /// </summary>
    /// <param name="uvAreaThreshold">The minimum UV area to consider. The default value is 1e-9f.</param>
    public void RecalculateUVDistributionMetrics(float uvAreaThreshold = 1E-09f)
    {
      if (this.canAccess)
        this.RecalculateUVDistributionMetricsImpl(uvAreaThreshold);
      else
        Debug.LogError((object) string.Format("Not allowed to call RecalculateUVDistributionMetrics() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Optimize mesh for frequent updates.</para>
    /// </summary>
    public void MarkDynamic()
    {
      if (!this.canAccess)
        return;
      this.MarkDynamicImpl();
    }

    /// <summary>
    ///   <para>Upload previously done Mesh modifications to the graphics API.</para>
    /// </summary>
    /// <param name="markNoLongerReadable">Frees up system memory copy of mesh data when set to true.</param>
    public void UploadMeshData(bool markNoLongerReadable)
    {
      if (!this.canAccess)
        return;
      this.UploadMeshDataImpl(markNoLongerReadable);
    }

    /// <summary>
    ///   <para>Optimizes the Mesh data to improve rendering performance.</para>
    /// </summary>
    public void Optimize()
    {
      if (this.canAccess)
        this.OptimizeImpl();
      else
        Debug.LogError((object) string.Format("Not allowed to call Optimize() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Optimizes the geometry of the Mesh to improve rendering performance.</para>
    /// </summary>
    public void OptimizeIndexBuffers()
    {
      if (this.canAccess)
        this.OptimizeIndexBuffersImpl();
      else
        Debug.LogError((object) string.Format("Not allowed to call OptimizeIndexBuffers() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Optimizes the vertices of the Mesh to improve rendering performance.</para>
    /// </summary>
    public void OptimizeReorderVertexBuffer()
    {
      if (this.canAccess)
        this.OptimizeReorderVertexBufferImpl();
      else
        Debug.LogError((object) string.Format("Not allowed to call OptimizeReorderVertexBuffer() on mesh '{0}'", (object) this.name));
    }

    /// <summary>
    ///   <para>Gets the topology of a sub-mesh.</para>
    /// </summary>
    /// <param name="submesh"></param>
    public MeshTopology GetTopology(int submesh)
    {
      if (submesh >= 0 && submesh < this.subMeshCount)
        return this.GetTopologyImpl(submesh);
      Debug.LogError((object) "Failed getting topology. Submesh index is out of bounds.", (Object) this);
      return MeshTopology.Triangles;
    }

    /// <summary>
    ///   <para>Combines several Meshes into this Mesh.</para>
    /// </summary>
    /// <param name="combine">Descriptions of the Meshes to combine.</param>
    /// <param name="mergeSubMeshes">Defines whether Meshes should be combined into a single sub-mesh.</param>
    /// <param name="useMatrices">Defines whether the transforms supplied in the CombineInstance array should be used or ignored.</param>
    /// <param name="hasLightmapData">Defines whether to transform the input Mesh lightmap UV data using the lightmap scale offset data in CombineInstance structs.</param>
    public void CombineMeshes(
      CombineInstance[] combine,
      [UnityEngine.Internal.DefaultValue("true")] bool mergeSubMeshes,
      [UnityEngine.Internal.DefaultValue("true")] bool useMatrices,
      [UnityEngine.Internal.DefaultValue("false")] bool hasLightmapData)
    {
      this.CombineMeshesImpl(combine, mergeSubMeshes, useMatrices, hasLightmapData);
    }

    /// <summary>
    ///   <para>Combines several Meshes into this Mesh.</para>
    /// </summary>
    /// <param name="combine">Descriptions of the Meshes to combine.</param>
    /// <param name="mergeSubMeshes">Defines whether Meshes should be combined into a single sub-mesh.</param>
    /// <param name="useMatrices">Defines whether the transforms supplied in the CombineInstance array should be used or ignored.</param>
    /// <param name="hasLightmapData">Defines whether to transform the input Mesh lightmap UV data using the lightmap scale offset data in CombineInstance structs.</param>
    [ExcludeFromDocs]
    public void CombineMeshes(CombineInstance[] combine, bool mergeSubMeshes, bool useMatrices)
    {
      this.CombineMeshesImpl(combine, mergeSubMeshes, useMatrices, false);
    }

    /// <summary>
    ///   <para>Combines several Meshes into this Mesh.</para>
    /// </summary>
    /// <param name="combine">Descriptions of the Meshes to combine.</param>
    /// <param name="mergeSubMeshes">Defines whether Meshes should be combined into a single sub-mesh.</param>
    /// <param name="useMatrices">Defines whether the transforms supplied in the CombineInstance array should be used or ignored.</param>
    /// <param name="hasLightmapData">Defines whether to transform the input Mesh lightmap UV data using the lightmap scale offset data in CombineInstance structs.</param>
    [ExcludeFromDocs]
    public void CombineMeshes(CombineInstance[] combine, bool mergeSubMeshes)
    {
      this.CombineMeshesImpl(combine, mergeSubMeshes, true, false);
    }

    /// <summary>
    ///   <para>Combines several Meshes into this Mesh.</para>
    /// </summary>
    /// <param name="combine">Descriptions of the Meshes to combine.</param>
    /// <param name="mergeSubMeshes">Defines whether Meshes should be combined into a single sub-mesh.</param>
    /// <param name="useMatrices">Defines whether the transforms supplied in the CombineInstance array should be used or ignored.</param>
    /// <param name="hasLightmapData">Defines whether to transform the input Mesh lightmap UV data using the lightmap scale offset data in CombineInstance structs.</param>
    [ExcludeFromDocs]
    public void CombineMeshes(CombineInstance[] combine)
    {
      this.CombineMeshesImpl(combine, true, true, false);
    }

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetVertexAttribute_Injected(int index, out VertexAttributeDescriptor ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetReadOnlySafetyHandle_Injected(
      Mesh.SafetyHandleIndex index,
      out AtomicSafetyHandle ret);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void SetSubMesh_Injected(
      int index,
      ref SubMeshDescriptor desc,
      MeshUpdateFlags flags = MeshUpdateFlags.Default);

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void GetSubMesh_Injected(int index, out SubMeshDescriptor ret);

    [SpecialName]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void get_bounds_Injected(out Bounds ret);

    [SpecialName]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void set_bounds_Injected(ref Bounds value);

    private enum SafetyHandleIndex
    {
      BonesPerVertexArray,
      BonesWeightsArray,
    }

    /// <summary>
    ///   <para>A struct containing Mesh data for C# Job System access.</para>
    /// </summary>
    [NativeHeader("Runtime/Graphics/Mesh/MeshScriptBindings.h")]
    [StaticAccessor("MeshDataBindings", StaticAccessorType.DoubleColon)]
    public struct MeshData
    {
      [NativeDisableUnsafePtrRestriction]
      internal IntPtr m_Ptr;
      internal AtomicSafetyHandle m_Safety;

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern bool HasVertexAttribute(IntPtr self, VertexAttribute attr);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetVertexAttributeDimension(IntPtr self, VertexAttribute attr);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern VertexAttributeFormat GetVertexAttributeFormat(
        IntPtr self,
        VertexAttribute attr);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetVertexAttributeStream(IntPtr self, VertexAttribute attr);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetVertexAttributeOffset(IntPtr self, VertexAttribute attr);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetVertexCount(IntPtr self);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetVertexBufferCount(IntPtr self);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern IntPtr GetVertexDataPtr(IntPtr self, int stream);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern ulong GetVertexDataSize(IntPtr self, int stream);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetVertexBufferStride(IntPtr self, int stream);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void CopyAttributeIntoPtr(
        IntPtr self,
        VertexAttribute attr,
        VertexAttributeFormat format,
        int dim,
        IntPtr dst);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void CopyIndicesIntoPtr(
        IntPtr self,
        int submesh,
        bool applyBaseVertex,
        int dstStride,
        IntPtr dst);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern IndexFormat GetIndexFormat(IntPtr self);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetIndexCount(IntPtr self, int submesh);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern IntPtr GetIndexDataPtr(IntPtr self);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern ulong GetIndexDataSize(IntPtr self);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern int GetSubMeshCount(IntPtr self);

      [NativeMethod(IsThreadSafe = true, ThrowsException = true)]
      private static SubMeshDescriptor GetSubMesh(IntPtr self, int index)
      {
        SubMeshDescriptor ret;
        Mesh.MeshData.GetSubMesh_Injected(self, index, out ret);
        return ret;
      }

      [NativeMethod(IsThreadSafe = true, ThrowsException = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void SetVertexBufferParamsFromPtr(
        IntPtr self,
        int vertexCount,
        IntPtr attributesPtr,
        int attributesCount);

      [NativeMethod(IsThreadSafe = true, ThrowsException = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void SetVertexBufferParamsFromArray(
        IntPtr self,
        int vertexCount,
        [Unmarshalled] params VertexAttributeDescriptor[] attributes);

      [NativeMethod(IsThreadSafe = true, ThrowsException = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void SetIndexBufferParamsImpl(
        IntPtr self,
        int indexCount,
        IndexFormat indexFormat);

      [NativeMethod(IsThreadSafe = true)]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void SetSubMeshCount(IntPtr self, int count);

      [NativeMethod(IsThreadSafe = true, ThrowsException = true)]
      private static void SetSubMeshImpl(
        IntPtr self,
        int index,
        SubMeshDescriptor desc,
        MeshUpdateFlags flags)
      {
        Mesh.MeshData.SetSubMeshImpl_Injected(self, index, ref desc, flags);
      }

      /// <summary>
      ///   <para>Gets the number of vertices in the MeshData. (Read Only)</para>
      /// </summary>
      public int vertexCount
      {
        get
        {
          this.CheckReadAccess();
          return Mesh.MeshData.GetVertexCount(this.m_Ptr);
        }
      }

      /// <summary>
      ///   <para>Gets the number of vertex buffers in the MeshData. (Read Only)</para>
      /// </summary>
      public int vertexBufferCount
      {
        get
        {
          this.CheckReadAccess();
          return Mesh.MeshData.GetVertexBufferCount(this.m_Ptr);
        }
      }

      /// <summary>
      ///   <para>Get the vertex buffer stream stride in bytes.</para>
      /// </summary>
      /// <param name="stream">The vertex data stream index to check for.</param>
      /// <returns>
      ///   <para>Vertex data size in bytes in this stream, or zero if the stream is not present.</para>
      /// </returns>
      public int GetVertexBufferStride(int stream)
      {
        this.CheckReadAccess();
        return Mesh.MeshData.GetVertexBufferStride(this.m_Ptr, stream);
      }

      /// <summary>
      ///   <para>Checks if a given vertex attribute exists in the MeshData.</para>
      /// </summary>
      /// <param name="attr">The vertex attribute to check for.</param>
      /// <returns>
      ///   <para>Returns true if the data attribute is present in the Mesh. Returns false if it is not.</para>
      /// </returns>
      public bool HasVertexAttribute(VertexAttribute attr)
      {
        this.CheckReadAccess();
        return Mesh.MeshData.HasVertexAttribute(this.m_Ptr, attr);
      }

      /// <summary>
      ///   <para>Gets the dimension of a given vertex attribute in the MeshData.</para>
      /// </summary>
      /// <param name="attr">The vertex attribute to get the dimension of.</param>
      /// <returns>
      ///   <para>Returns the dimension of the vertex attribute. Returns 0 if the vertex attribute is not present.</para>
      /// </returns>
      public int GetVertexAttributeDimension(VertexAttribute attr)
      {
        this.CheckReadAccess();
        return Mesh.MeshData.GetVertexAttributeDimension(this.m_Ptr, attr);
      }

      /// <summary>
      ///   <para>Gets the format of a given vertex attribute in the MeshData.</para>
      /// </summary>
      /// <param name="attr">The vertex attribute to check the format of.</param>
      /// <returns>
      ///   <para>Returns the format of the given vertex attribute.</para>
      /// </returns>
      public VertexAttributeFormat GetVertexAttributeFormat(VertexAttribute attr)
      {
        this.CheckReadAccess();
        return Mesh.MeshData.GetVertexAttributeFormat(this.m_Ptr, attr);
      }

      /// <summary>
      ///   <para>Get the vertex buffer stream index of a specific vertex data attribute on this MeshData.</para>
      /// </summary>
      /// <param name="attr">The vertex data attribute to check for.</param>
      /// <returns>
      ///   <para>Stream index of the data attribute, or -1 if it is not present.</para>
      /// </returns>
      public int GetVertexAttributeStream(VertexAttribute attr)
      {
        this.CheckReadAccess();
        return Mesh.MeshData.GetVertexAttributeStream(this.m_Ptr, attr);
      }

      /// <summary>
      ///   <para>Gets the offset within a vertex buffer stream of a given vertex data attribute on this MeshData.</para>
      /// </summary>
      /// <param name="attr">The vertex data attribute to check for.</param>
      /// <returns>
      ///   <para>The byte offset within a atream of the data attribute, or -1 if it is not present.</para>
      /// </returns>
      public int GetVertexAttributeOffset(VertexAttribute attr)
      {
        this.CheckReadAccess();
        return Mesh.MeshData.GetVertexAttributeOffset(this.m_Ptr, attr);
      }

      public void GetVertices(NativeArray<Vector3> outVertices)
      {
        this.CopyAttributeInto<Vector3>(outVertices, VertexAttribute.Position, VertexAttributeFormat.Float32, 3);
      }

      public void GetNormals(NativeArray<Vector3> outNormals)
      {
        this.CopyAttributeInto<Vector3>(outNormals, VertexAttribute.Normal, VertexAttributeFormat.Float32, 3);
      }

      public void GetTangents(NativeArray<Vector4> outTangents)
      {
        this.CopyAttributeInto<Vector4>(outTangents, VertexAttribute.Tangent, VertexAttributeFormat.Float32, 4);
      }

      public void GetColors(NativeArray<Color> outColors)
      {
        this.CopyAttributeInto<Color>(outColors, VertexAttribute.Color, VertexAttributeFormat.Float32, 4);
      }

      public void GetColors(NativeArray<Color32> outColors)
      {
        this.CopyAttributeInto<Color32>(outColors, VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4);
      }

      public void GetUVs(int channel, NativeArray<Vector2> outUVs)
      {
        if (channel < 0 || channel > 7)
          throw new ArgumentOutOfRangeException(nameof (channel), (object) channel, "The uv index is invalid. Must be in the range 0 to 7.");
        this.CopyAttributeInto<Vector2>(outUVs, Mesh.GetUVChannel(channel), VertexAttributeFormat.Float32, 2);
      }

      public void GetUVs(int channel, NativeArray<Vector3> outUVs)
      {
        if (channel < 0 || channel > 7)
          throw new ArgumentOutOfRangeException(nameof (channel), (object) channel, "The uv index is invalid. Must be in the range 0 to 7.");
        this.CopyAttributeInto<Vector3>(outUVs, Mesh.GetUVChannel(channel), VertexAttributeFormat.Float32, 3);
      }

      public void GetUVs(int channel, NativeArray<Vector4> outUVs)
      {
        if (channel < 0 || channel > 7)
          throw new ArgumentOutOfRangeException(nameof (channel), (object) channel, "The uv index is invalid. Must be in the range 0 to 7.");
        this.CopyAttributeInto<Vector4>(outUVs, Mesh.GetUVChannel(channel), VertexAttributeFormat.Float32, 4);
      }

      public unsafe NativeArray<T> GetVertexData<T>([UnityEngine.Internal.DefaultValue("0")] int stream = 0) where T : struct
      {
        this.CheckReadAccess();
        ulong num1 = stream >= 0 && stream < this.vertexBufferCount ? Mesh.MeshData.GetVertexDataSize(this.m_Ptr, stream) : throw new ArgumentOutOfRangeException(string.Format("{0} out of bounds, should be below {1} but was {2}", (object) nameof (stream), (object) this.vertexBufferCount, (object) stream));
        ulong num2 = (ulong) UnsafeUtility.SizeOf<T>();
        if (num1 % num2 > 0UL)
          throw new ArgumentException(string.Format("Type passed to {0} can't capture the vertex buffer. Mesh vertex buffer size is {1} which is not a multiple of type size {2}", (object) nameof (GetVertexData), (object) num1, (object) num2));
        ulong length = num1 / num2;
        NativeArray<T> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<T>((void*) Mesh.MeshData.GetVertexDataPtr(this.m_Ptr, stream), (int) length, Allocator.None);
        NativeArrayUnsafeUtility.SetAtomicSafetyHandle<T>(ref nativeArray, this.m_Safety);
        return nativeArray;
      }

      private unsafe void CopyAttributeInto<T>(
        NativeArray<T> buffer,
        VertexAttribute channel,
        VertexAttributeFormat format,
        int dim)
        where T : struct
      {
        this.CheckReadAccess();
        if (!this.HasVertexAttribute(channel))
          throw new InvalidOperationException(string.Format("Mesh data does not have {0} vertex component", (object) channel));
        if (buffer.Length < this.vertexCount)
          throw new InvalidOperationException(string.Format("Not enough space in output buffer (need {0}, has {1})", (object) this.vertexCount, (object) buffer.Length));
        Mesh.MeshData.CopyAttributeIntoPtr(this.m_Ptr, channel, format, dim, (IntPtr) buffer.GetUnsafePtr<T>());
      }

      /// <summary>
      ///   <para>Sets the vertex buffer size and layout of the Mesh that Unity creates from the MeshData.</para>
      /// </summary>
      /// <param name="vertexCount">The number of vertices in the Mesh.</param>
      /// <param name="attributes">Layout of the vertex data: which attributes are present, their data types and so on.</param>
      public void SetVertexBufferParams(
        int vertexCount,
        params VertexAttributeDescriptor[] attributes)
      {
        this.CheckWriteAccess();
        Mesh.MeshData.SetVertexBufferParamsFromArray(this.m_Ptr, vertexCount, attributes);
      }

      public unsafe void SetVertexBufferParams(
        int vertexCount,
        NativeArray<VertexAttributeDescriptor> attributes)
      {
        this.CheckWriteAccess();
        Mesh.MeshData.SetVertexBufferParamsFromPtr(this.m_Ptr, vertexCount, (IntPtr) attributes.GetUnsafeReadOnlyPtr<VertexAttributeDescriptor>(), attributes.Length);
      }

      /// <summary>
      ///   <para>Sets the index buffer size and format of the Mesh that Unity creates from the MeshData.</para>
      /// </summary>
      /// <param name="indexCount">The size of the index buffer.</param>
      /// <param name="format">The format of the indices.</param>
      public void SetIndexBufferParams(int indexCount, IndexFormat format)
      {
        this.CheckWriteAccess();
        Mesh.MeshData.SetIndexBufferParamsImpl(this.m_Ptr, indexCount, format);
      }

      /// <summary>
      ///   <para>Gets the format of the index buffer data in the MeshData. (Read Only)</para>
      /// </summary>
      public IndexFormat indexFormat
      {
        get
        {
          this.CheckReadAccess();
          return Mesh.MeshData.GetIndexFormat(this.m_Ptr);
        }
      }

      public unsafe void GetIndices(
        NativeArray<ushort> outIndices,
        int submesh,
        [UnityEngine.Internal.DefaultValue("true")] bool applyBaseVertex = true)
      {
        this.CheckReadAccess();
        int num = submesh >= 0 && submesh < this.subMeshCount ? Mesh.MeshData.GetIndexCount(this.m_Ptr, submesh) : throw new IndexOutOfRangeException(string.Format("Specified submesh ({0}) is out of range. Must be greater or equal to 0 and less than subMeshCount ({1}).", (object) submesh, (object) this.subMeshCount));
        if (outIndices.Length < num)
          throw new InvalidOperationException(string.Format("Not enough space in output buffer (need {0}, has {1})", (object) num, (object) outIndices.Length));
        Mesh.MeshData.CopyIndicesIntoPtr(this.m_Ptr, submesh, applyBaseVertex, 2, (IntPtr) outIndices.GetUnsafePtr<ushort>());
      }

      public unsafe void GetIndices(NativeArray<int> outIndices, int submesh, [UnityEngine.Internal.DefaultValue("true")] bool applyBaseVertex = true)
      {
        this.CheckReadAccess();
        int num = submesh >= 0 && submesh < this.subMeshCount ? Mesh.MeshData.GetIndexCount(this.m_Ptr, submesh) : throw new IndexOutOfRangeException(string.Format("Specified submesh ({0}) is out of range. Must be greater or equal to 0 and less than subMeshCount ({1}).", (object) submesh, (object) this.subMeshCount));
        if (outIndices.Length < num)
          throw new InvalidOperationException(string.Format("Not enough space in output buffer (need {0}, has {1})", (object) num, (object) outIndices.Length));
        Mesh.MeshData.CopyIndicesIntoPtr(this.m_Ptr, submesh, applyBaseVertex, 4, (IntPtr) outIndices.GetUnsafePtr<int>());
      }

      public unsafe NativeArray<T> GetIndexData<T>() where T : struct
      {
        this.CheckReadAccess();
        ulong indexDataSize = Mesh.MeshData.GetIndexDataSize(this.m_Ptr);
        ulong num = (ulong) UnsafeUtility.SizeOf<T>();
        if (indexDataSize % num > 0UL)
          throw new ArgumentException(string.Format("Type passed to {0} can't capture the index buffer. Mesh index buffer size is {1} which is not a multiple of type size {2}", (object) nameof (GetIndexData), (object) indexDataSize, (object) num));
        ulong length = indexDataSize / num;
        NativeArray<T> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<T>((void*) Mesh.MeshData.GetIndexDataPtr(this.m_Ptr), (int) length, Allocator.None);
        NativeArrayUnsafeUtility.SetAtomicSafetyHandle<T>(ref nativeArray, this.m_Safety);
        return nativeArray;
      }

      /// <summary>
      ///   <para>The number of sub-meshes in the MeshData.</para>
      /// </summary>
      public int subMeshCount
      {
        get
        {
          this.CheckReadAccess();
          return Mesh.MeshData.GetSubMeshCount(this.m_Ptr);
        }
        set
        {
          this.CheckWriteAccess();
          Mesh.MeshData.SetSubMeshCount(this.m_Ptr, value);
        }
      }

      /// <summary>
      ///   <para>Gets data about a given sub-mesh in the MeshData.</para>
      /// </summary>
      /// <param name="index">The index of the sub-mesh. See Mesh.MeshData.subMeshCount|subMeshCount. If you specify an out of range index, Unity throws an exception.</param>
      /// <returns>
      ///   <para>Returns sub-mesh data.</para>
      /// </returns>
      public SubMeshDescriptor GetSubMesh(int index)
      {
        this.CheckReadAccess();
        return Mesh.MeshData.GetSubMesh(this.m_Ptr, index);
      }

      /// <summary>
      ///   <para>Sets the data for a sub-mesh of the Mesh that Unity creates from the MeshData.</para>
      /// </summary>
      /// <param name="index">The index of the sub-mesh to set data for. See Mesh.MeshData.subMeshCount|subMeshCount. If you specify an out of range index, Unity throws an exception.</param>
      /// <param name="desc">Sub-mesh data.</param>
      /// <param name="flags">Flags controlling the function behavior. See MeshUpdateFlags.</param>
      public void SetSubMesh(int index, SubMeshDescriptor desc, MeshUpdateFlags flags = MeshUpdateFlags.Default)
      {
        this.CheckWriteAccess();
        Mesh.MeshData.SetSubMeshImpl(this.m_Ptr, index, desc, flags);
      }

      [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
      private void CheckReadAccess() => AtomicSafetyHandle.CheckReadAndThrow(this.m_Safety);

      [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
      private void CheckWriteAccess() => AtomicSafetyHandle.CheckWriteAndThrow(this.m_Safety);

      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void GetSubMesh_Injected(
        IntPtr self,
        int index,
        out SubMeshDescriptor ret);

      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void SetSubMeshImpl_Injected(
        IntPtr self,
        int index,
        ref SubMeshDescriptor desc,
        MeshUpdateFlags flags);
    }

    /// <summary>
    ///   <para>An array of Mesh data snapshots for C# Job System access.</para>
    /// </summary>
    [NativeContainerSupportsMinMaxWriteRestriction]
    [NativeContainer]
    [StaticAccessor("MeshDataArrayBindings", StaticAccessorType.DoubleColon)]
    public struct MeshDataArray : IDisposable
    {
      [NativeDisableUnsafePtrRestriction]
      private unsafe IntPtr* m_Ptrs;
      internal int m_Length;
      internal int m_MinIndex;
      internal int m_MaxIndex;
      private AtomicSafetyHandle m_Safety;
      [NativeSetClassTypeToNullOnSchedule]
      private DisposeSentinel m_DisposeSentinel;

      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern unsafe void AcquireReadOnlyMeshData([NotNull("ArgumentNullException")] Mesh mesh, IntPtr* datas);

      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern unsafe void AcquireReadOnlyMeshDatas(
        [NotNull("ArgumentNullException")] Mesh[] meshes,
        IntPtr* datas,
        int count);

      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern unsafe void ReleaseMeshDatas(IntPtr* datas, int count);

      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern unsafe void CreateNewMeshDatas(IntPtr* datas, int count);

      [NativeThrows]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern unsafe void ApplyToMeshesImpl(
        [NotNull("ArgumentNullException")] Mesh[] meshes,
        IntPtr* datas,
        int count,
        MeshUpdateFlags flags);

      [NativeThrows]
      [MethodImpl(MethodImplOptions.InternalCall)]
      private static extern void ApplyToMeshImpl([NotNull("ArgumentNullException")] Mesh mesh, IntPtr data, MeshUpdateFlags flags);

      /// <summary>
      ///   <para>Number of Mesh data elements in the MeshDataArray.</para>
      /// </summary>
      public int Length => this.m_Length;

      public unsafe Mesh.MeshData this[int index]
      {
        get
        {
          this.CheckElementReadAccess(index);
          Mesh.MeshData meshData;
          meshData.m_Ptr = this.m_Ptrs[index];
          meshData.m_Safety = this.m_Safety;
          return meshData;
        }
      }

      /// <summary>
      ///   <para>Use this method to dispose of the MeshDataArray struct.</para>
      /// </summary>
      public unsafe void Dispose()
      {
        DisposeSentinel.Dispose(ref this.m_Safety, ref this.m_DisposeSentinel);
        if (this.m_Length != 0)
        {
          Mesh.MeshDataArray.ReleaseMeshDatas(this.m_Ptrs, this.m_Length);
          UnsafeUtility.Free((void*) this.m_Ptrs, Allocator.Persistent);
        }
        this.m_Ptrs = (IntPtr*) null;
        this.m_Length = 0;
      }

      internal unsafe void ApplyToMeshAndDispose(Mesh mesh, MeshUpdateFlags flags)
      {
        if (!mesh.canAccess)
          throw new InvalidOperationException("Not allowed to access vertex data on mesh '" + mesh.name + "' (isReadable is false; Read/Write must be enabled in import settings)");
        Mesh.MeshDataArray.ApplyToMeshImpl(mesh, *this.m_Ptrs, flags);
        this.Dispose();
      }

      internal unsafe void ApplyToMeshesAndDispose(Mesh[] meshes, MeshUpdateFlags flags)
      {
        for (int index = 0; index < this.m_Length; ++index)
        {
          Mesh mesh = meshes[index];
          if ((Object) mesh == (Object) null)
            throw new ArgumentNullException(nameof (meshes), string.Format("Mesh at index {0} is null", (object) index));
          if (!mesh.canAccess)
            throw new InvalidOperationException(string.Format("Not allowed to access vertex data on mesh '{0}' at array index {1} (isReadable is false; Read/Write must be enabled in import settings)", (object) mesh.name, (object) index));
        }
        Mesh.MeshDataArray.ApplyToMeshesImpl(meshes, this.m_Ptrs, this.m_Length, flags);
        this.Dispose();
      }

      internal unsafe MeshDataArray(Mesh mesh, bool checkReadWrite = true)
      {
        if ((Object) mesh == (Object) null)
          throw new ArgumentNullException(nameof (mesh), "Mesh is null");
        if (checkReadWrite && !mesh.canAccess)
          throw new InvalidOperationException("Not allowed to access vertex data on mesh '" + mesh.name + "' (isReadable is false; Read/Write must be enabled in import settings)");
        this.m_Length = 1;
        this.m_Ptrs = (IntPtr*) UnsafeUtility.Malloc((long) UnsafeUtility.SizeOf<IntPtr>(), UnsafeUtility.AlignOf<IntPtr>(), Allocator.Persistent);
        Mesh.MeshDataArray.AcquireReadOnlyMeshData(mesh, this.m_Ptrs);
        this.m_MinIndex = 0;
        this.m_MaxIndex = this.m_Length - 1;
        DisposeSentinel.Create(out this.m_Safety, out this.m_DisposeSentinel, 1, Allocator.TempJob);
        AtomicSafetyHandle.SetAllowSecondaryVersionWriting(this.m_Safety, false);
        AtomicSafetyHandle.UseSecondaryVersion(ref this.m_Safety);
      }

      internal unsafe MeshDataArray(Mesh[] meshes, int meshesCount, bool checkReadWrite = true)
      {
        if (meshes.Length < meshesCount)
          throw new InvalidOperationException(string.Format("Meshes array size ({0}) is smaller than meshes count ({1})", (object) meshes.Length, (object) meshesCount));
        for (int index = 0; index < meshesCount; ++index)
        {
          Mesh mesh = meshes[index];
          if ((Object) mesh == (Object) null)
            throw new ArgumentNullException(nameof (meshes), string.Format("Mesh at index {0} is null", (object) index));
          if (checkReadWrite && !mesh.canAccess)
            throw new InvalidOperationException(string.Format("Not allowed to access vertex data on mesh '{0}' at array index {1} (isReadable is false; Read/Write must be enabled in import settings)", (object) mesh.name, (object) index));
        }
        this.m_Length = meshesCount;
        this.m_Ptrs = (IntPtr*) UnsafeUtility.Malloc((long) (UnsafeUtility.SizeOf<IntPtr>() * meshesCount), UnsafeUtility.AlignOf<IntPtr>(), Allocator.Persistent);
        Mesh.MeshDataArray.AcquireReadOnlyMeshDatas(meshes, this.m_Ptrs, meshesCount);
        this.m_MinIndex = 0;
        this.m_MaxIndex = this.m_Length - 1;
        DisposeSentinel.Create(out this.m_Safety, out this.m_DisposeSentinel, 1, Allocator.TempJob);
        AtomicSafetyHandle.SetAllowSecondaryVersionWriting(this.m_Safety, false);
        AtomicSafetyHandle.UseSecondaryVersion(ref this.m_Safety);
      }

      internal unsafe MeshDataArray(int meshesCount)
      {
        this.m_Length = meshesCount >= 0 ? meshesCount : throw new InvalidOperationException(string.Format("Mesh count can not be negative (was {0})", (object) meshesCount));
        this.m_Ptrs = (IntPtr*) UnsafeUtility.Malloc((long) (UnsafeUtility.SizeOf<IntPtr>() * meshesCount), UnsafeUtility.AlignOf<IntPtr>(), Allocator.Persistent);
        Mesh.MeshDataArray.CreateNewMeshDatas(this.m_Ptrs, meshesCount);
        this.m_MinIndex = 0;
        this.m_MaxIndex = this.m_Length - 1;
        DisposeSentinel.Create(out this.m_Safety, out this.m_DisposeSentinel, 1, Allocator.TempJob);
      }

      [Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
      private void CheckElementReadAccess(int index)
      {
        if (index < this.m_MinIndex || index > this.m_MaxIndex)
          this.FailOutOfRangeError(index);
        AtomicSafetyHandle.CheckReadAndThrow(this.m_Safety);
      }

      [BurstDiscard]
      private void FailOutOfRangeError(int index)
      {
        if (index < this.Length && (this.m_MinIndex != 0 || this.m_MaxIndex != this.Length - 1))
          throw new IndexOutOfRangeException(string.Format("Index {0} is out of restricted IJobParallelFor range [{1}...{2}] in {3}.\n", (object) index, (object) this.m_MinIndex, (object) this.m_MaxIndex, (object) nameof (MeshDataArray)) + "You can only access the element at the job index, unless [NativeDisableParallelForRestriction] is used on the variable.");
        throw new IndexOutOfRangeException(string.Format("Index {0} is out of range of '{1}' Length.", (object) index, (object) this.Length));
      }
    }
  }
}
